home *** CD-ROM | disk | FTP | other *** search
/ Aminet 21 / Aminet 21 (1997)(GTI - Schatztruhe)[!][Oct 1997].iso / Aminet / dev / misc / FD2Pragma.lha / Source / FD2Pragma.c next >
Encoding:
C/C++ Source or Header  |  1997-08-02  |  72.8 KB  |  3,044 lines

  1. #define NAME     "FD2Pragma"
  2. #define VERSION  "2"
  3. #define REVISION "39"
  4. #define ENDCODE
  5. //#define DEBUG
  6. //#define DEBUG_OLD
  7.  
  8. /* Programmheader
  9.  
  10.     Name:        FD2Pragma
  11.     Author:     SDI
  12.     Distribution:    PD
  13.     Description:    creates pragmas files, lvo files and stub functions
  14.     Compileropts:    -
  15.     Linkeropts:    -gd
  16.     Bugs:        CLIB scan does not recognize functions getting a
  17.             function as parameter, CPP name for functions:
  18.             'PF' <returnvalue> <parameters> 'p'
  19.  
  20.  1.2    : added pragmas for the Dice compiler. Available via switch "Dice".
  21.     added switches "Aztec", "SAS" and "Maxon": Maxon and Aztec just
  22.     turn on the default (except that Maxon expects pragma files to be
  23.     called "xxx_pragmas.h" instead of "xxx_lib.h"), SAS is equal to
  24.     Dice, except that SAS supports the pragma tagcall.
  25.  2.0    : Added support for tag functions. See the docs for details.
  26.     Author until this version:
  27.     Jochen Wiedmann
  28.     Am Eisteich 9
  29.     72555 Metzingen (Germany)
  30.     Tel. 07123 / 14881
  31.     E-Mail: wiedmann@mailserv.zdv.uni-tuebingen.de
  32.  2.1   19.08.96 : now made by SDI, added correct __MAXON__ support and
  33.     support for StormC++, added auto recognition of tagcall functions
  34.     changed the CLI interface completely
  35.  2.2   21.08.96 : fixed a lot of errors, added debug code
  36.  2.3   22.08.96 : little changes
  37.  2.4   24.08.96 : added proto-file creation
  38.  2.5   25.08.96 : added syscall and fix for functions ending in ...DMA
  39.  2.6   26.08.96 : fixed some errors, added CLIB parameter (used later for
  40.     CSTUBS)
  41.  2.7   01.09.96 : added correct Storm definition, added CLIB scan
  42.  2.8   02.09.96 : added assembler stub functions, added first ASM-stub code
  43.  2.9   04.09.96 : added Comment-Support
  44.  2.10  05.09.96 : changed CSTUB creation a bit
  45.  2.11  07.09.96 : speeded up output, reduced number of strndup calls
  46.  2.12  26.09.96 : pressing CTRL-C in early startup brought an wrong error
  47.     message - fixed
  48.  2.13  30.09.96 : made RegNames field to RegNames string - shorter Exe-file
  49.  2.14  01.10.96 : made SPECIAL 6 default, COMMENT also in LVO files
  50.  2.15  13.10.96 : corrected an error text
  51.  2.16  14.10.96 : added correct comment support and PRIVATE option
  52.  2.17  19.10.96 : now Maxon-compiled in Small data mode
  53.  2.18  22.10.96 : removed EXTERNC in Storm, Maxon and all pragmas, corrected
  54.     the texts
  55.  2.19  26.10.96 : added option to create FD files out of pragma files,
  56.     reworked a lot in the source
  57.  2.20  27.10.96 : fixed errors of previous version
  58.  2.21  28.10.96 : fixed error im CLIB scan
  59.  2.22  27.11.96 : SPECIAL numbers for lib and ASM code were wrong, removed
  60.     bug in Tag function stubs
  61.  2.23  06.12.96 : lib and stub creation still was wrong
  62.  2.24  31.12.96 : formed stub libs matching C++ file names, corrected CLIB
  63.     scan errors
  64.  2.25  04.01.97 : added HEADER option (I was asked for)
  65.  2.26  05.01.97 : added HEADER scan (in old file) and auto inserting
  66.  2.27  10.01.97 : stub functions missed register saving, outfuncs skip now,
  67.     when error occured (makes lots of error checking obsolete)
  68.  2.28  11.01.97 : forgot to add offset made by register saving
  69.  2.29  18.01.97 : now libtags and amitags defines only, when at least 1
  70.     tagfunc
  71.  2.30  13.02.97 : added local library base functions, rearranged SPECIAL
  72.           options, fixed some bugs
  73.  2.31  15.02.97 : corrected bugs inserted in previous version
  74.  2.32  16.02.97 : and again bug fixes, still didn't work
  75.  2.33  18.02.97 : corrected texts, added SPECIAL 28
  76.  2.34  25.03.97 : corrected Pragma --> FD file conversion, added ##shadow
  77.  2.35  26.03.97 : added STORMFD option, COMMENT, PRIVATE work again
  78.  2.36  29.03.97 : corrected *tagcall scan a bit
  79.  2.37  20.06.97 : added PASCAL stub lib production (SPECIAL 14, 15)
  80.  2.38  01.07.97 : fixed ##end handling
  81.  2.39  20.07.97 : added better proto file (__GNUC__ inline and pragma call),
  82.     removed C++ comments
  83. */
  84.  
  85. #include <exec/memory.h>
  86. #include <dos/doshunks.h>
  87.  
  88. #include <proto/exec.h>
  89. #include <proto/dos.h>
  90. #include <proto/intuition.h>
  91.  
  92. #define SDI_TO_ANSI        /* Replaces ANSI functions with my ASM ones */
  93. #include "SDI_ASM_STD_protos.h" /* You may use <stdio.h> and <stdlib.h> instead. */
  94. #include "SDI_defines.h"
  95. #include "SDI_structures.h"
  96.  
  97. #define TEXT_SAS    "__SASC"    /* verified    */
  98. #define TEXT_SAS_60    "__SASC_60"    /* verified    */
  99. #define TEXT_MAXON    "__MAXON__"    /* verified    */
  100. #define TEXT_STORM    "__STORM__"    /* verified    */
  101. #define TEXT_DICE    "_DCC"        /* in 2.0 code    */
  102. #define TEXT_AZTEC    "AZTEC_C"    /* verified    */
  103. #define TEXT_GNUC    "__GNUC__"    /* verified    */
  104.  
  105. #define FLAG_EXTERNC    (1<<0)
  106. #define FLAG_SYSCALL    (1<<1)
  107. #define FLAG_DOCOMMENT    (1<<2)
  108. #define FLAG_PRIVATE    (1<<3)
  109. #define FLAG_LOCALREG    (1<<4)
  110. #define FLAG_STORMFD    (1<<5)
  111. #define FLAG_PASCAL    (1<<6)
  112.  
  113. #define MODUS_STUBTEXT    1
  114. #define MODUS_STUBCODE    2
  115. #define MODUS_LOCALDATA 3
  116. #define MODUS_PRAGMA    4
  117. #define MODUS_LVO    10    /* and 11 and 12 and 13     */
  118. #define MODUS_PROTO    20    /* and 20 and 21 and 22 and 23    */
  119. #define MODUS_ERROR    100
  120.  
  121. #define TAGMODE_NORMAL    0
  122. #define TAGMODE_TAGS    1
  123. #define TAGMODE_BOTH    2
  124.  
  125. #define PARAM "FROM=FDFILE/A,SPECIAL/N,TO/K,COMMENT/S,MODE/N,AMICALL/K," \
  126.     "LIBCALL/K,AMITAGS/K,LIBTAGS/K,CSTUBS/K,EXTERNC/S,USESYSCALL/S," \
  127.     "CLIB/K,PRIVATE/S,HEADER/K,STORMFD/S"
  128.  
  129. UBYTE RegNames[] =
  130. "d0\0\0" "d1\0\0" "d2\0\0" "d3\0\0" "d4\0\0" "d5\0\0" "d6\0\0" "d7\0\0"
  131. "a0\0\0" "a1\0\0" "a2\0\0" "a3\0\0" "a4\0\0" "a5\0\0" "a6\0\0" "a7";
  132. /* double zero, to make the finding easier (by using <<2 instead of *3) */
  133.  
  134. struct ShortList {
  135.   struct ShortList    *Next;
  136. };
  137.  
  138. struct ShortListRoot {
  139.   struct ShortList    *First;
  140.   struct ShortList    *Last;
  141.   ULONG         Size;
  142. };
  143.  
  144. struct AmiPragma {
  145.   struct ShortList    List;
  146.   UWORD         Bias;
  147.   UWORD         Public;
  148.   STRPTR        FuncName;
  149.   STRPTR        TagName;
  150.   UWORD         NumArgs;
  151.   struct AmiArgs
  152.   {
  153.     STRPTR        ArgName;
  154.     UWORD        ArgReg;
  155.   } Args[14];    /*  a6 and a7 must not be used for function arguments    */
  156. };
  157.  
  158. struct Comment {
  159.   struct ShortList    List;
  160.   STRPTR        Data;
  161.   UWORD         Bias;
  162. };
  163.  
  164. struct PragList {
  165.   struct ShortList    List;
  166.   STRPTR        Basename;
  167.   struct ShortListRoot    Data;
  168. };
  169.  
  170. struct PragData {
  171.   struct ShortList    List;
  172.   ULONG         NumNames;
  173.   ULONG         NumArgs;
  174.   UBYTE         ArgReg[14];
  175.   ULONG         Bias;
  176.   struct ShortListRoot    Name;
  177. };
  178.  
  179. struct FDData {
  180.   STRPTR    Name;
  181.   STRPTR    Basename;
  182.   ULONG     NumArgs;
  183.   UBYTE     ArgReg[14];
  184.   ULONG     Bias;
  185.   ULONG     Mode;        /* 0 = Normal, != 0 is TagName */
  186. };
  187.  
  188. #define CPP_TYPE_VOID        'v'    /* void,    VOID    */
  189. #define CPP_TYPE_BYTE        'c'    /* char,    BYTE    */
  190. #define CPP_TYPE_WORD        's'    /* short,    WORD    */
  191. #define CPP_TYPE_LONG        'j'    /* long,    LONG    */
  192. #define CPP_TYPE_FLOAT        'f'    /* float,    FLOAT    */
  193. #define CPP_TYPE_DOUBLE     'd'    /* double,    DOUBLE    */
  194. #define CPP_TYPE_STRUCTURE    0
  195. #define CPP_TYPE_VARARGS    'e'
  196.  
  197. #define CPP_FLAG_UNSIGNED    (1<<0)
  198. #define CPP_FLAG_CONST        (1<<1)
  199. #define CPP_FLAG_STRPTR     (1<<2)
  200. #define CPP_FLAG_POINTER    (1<<3)
  201. /* STRPTR is defined different under C and CPP -> I have to create two
  202. names, one time unsigned char *, one time signed char *, when somewhere
  203. a STRPTR occurs */
  204.  
  205. struct CPP_NameType {
  206.   STRPTR    StructureName;     /* if a structure only      */
  207.   UWORD     StructureLength; /* length of the structure name */
  208.   UBYTE     Type;         /* see above defines         */
  209.   UBYTE     Flags;         /* see above flags         */
  210.   UWORD     PointerDepth;     /* number of * in type      */
  211. };  
  212.  
  213. struct CPP_TypeField {
  214.   STRPTR    Text;
  215.   UWORD     Length;
  216.   UBYTE     Flags;
  217.   UBYTE     Type;
  218. };
  219.  
  220. struct Proto_LibTypes {
  221.   STRPTR    BaseName;
  222.   STRPTR    StructureName;
  223. };
  224.  
  225. #define NTP_NORMAL    0    /* no tags/args     */
  226. #define NTP_TAGS    1    /* TagFunction        */
  227. #define NTP_ARGS    2    /* ArgFunction        */
  228. #define NTP_UNKNOWN    3    /* CommentFunction    */
  229.  
  230. struct NameList {
  231.   struct ShortList    List;
  232.   ULONG         Type;    /* set by OptimizeFDData */
  233.   STRPTR        NormName;
  234.   STRPTR        PragName;
  235. };
  236.  
  237. struct RDArgs    *rda            = 0;
  238. struct SDI_InOut in            = {0,0,0,0,0},
  239.          out            = {0,0,5120,0,0};
  240. STRPTR        clibbuf         = 0;
  241. ULONG        clibsize        = 0;
  242. struct FileInfoBlock *fib        = 0;
  243. struct ShortListRoot    AmiPragma    = {0,0,sizeof(struct AmiPragma)},
  244.             Comment     = {0,0,sizeof(struct Comment)};
  245. struct Remember *remember        = 0;
  246. ULONG        oldfh            = 0;
  247. ULONG        lock            = 0;
  248. STRPTR        BaseName        = 0;
  249. STRPTR        ShortBaseName        = 0;
  250. STRPTR        ShortBaseNameUpper    = 0;
  251. ULONG        DosVersion        = 37; /* force OS2.0 */
  252. ULONG        MODE            = 1;
  253. STRPTR        AMICALL         = 0;
  254. STRPTR        LIBCALL         = 0;
  255. STRPTR        AMITAGS         = 0;
  256. STRPTR        LIBTAGS         = 0;
  257. STRPTR        CSTUBS            = 0;
  258. STRPTR        HEADER            = 0;
  259. ULONG        headersize        = 0;
  260. ULONG        Flags            = 0;
  261. struct IntuitionBase *IntuitionBase    = 0;
  262. ULONG        Output_Error        = 1; /* Output error occured when 0 */
  263. ULONG        tagfuncs        = 0; /* are there some tagfuncs in FD */
  264. UBYTE        deftype[]        = "ULONG";
  265.  
  266. /* Prototypes for the functions */
  267. STRPTR strndup(STRPTR, ULONG);
  268. void DoError(UBYTE, ULONG, ...);
  269. ULONG Out(ULONG);
  270. ULONG DoOutput(STRPTR, ...);
  271. ULONG DoOutputDirect(APTR, ULONG);
  272. STRPTR SkipBlanks(STRPTR);
  273. STRPTR SkipName(STRPTR);
  274. ULONG MakeTagFunction(struct AmiPragma *);
  275. void MakeLines(STRPTR, ULONG, ULONG);
  276. ULONG ScanFDFile(void);
  277. void FindHeader(void);
  278. ULONG GetRegisterData(struct AmiPragma *);
  279. ULONG OutputXDEF(STRPTR, ...);
  280. /* ------------------------------------------------------------------ */
  281. struct ShortList *NewItem(struct ShortListRoot *);
  282. struct ShortList *RemoveItem(struct ShortListRoot *, struct ShortList *);
  283. void          AddItem(struct ShortListRoot *, struct ShortList *);
  284. /* ------------------------------------------------------------------ */
  285. ULONG FuncAMICALL(struct AmiPragma *, ULONG);
  286. ULONG FuncLIBCALL(struct AmiPragma *, ULONG);
  287. ULONG FuncAsmText(struct AmiPragma *, ULONG);
  288. ULONG FuncAsmCode(struct AmiPragma *, ULONG);
  289. ULONG FuncCSTUBS (struct AmiPragma *, ULONG);
  290. ULONG FuncLVOXDEF(struct AmiPragma *, ULONG);
  291. ULONG FuncLVO     (struct AmiPragma *, ULONG);
  292. ULONG FuncLocCode(struct AmiPragma *, ULONG);
  293. ULONG FuncLocText(struct AmiPragma *, ULONG);
  294. ULONG CallFunc(ULONG, STRPTR, ULONG (*) (struct AmiPragma *, ULONG));
  295. /* ------------------------------------------------------------------ */
  296. ULONG CopyCPPType(STRPTR, STRPTR, ULONG, STRPTR, struct AmiArgs *);
  297. void GetCPPType(struct CPP_NameType *, STRPTR);
  298. STRPTR FindClibFunc(STRPTR);    /* finds the needed function */
  299. ULONG GetClibLength(STRPTR);    /* returns length of the type */
  300. ULONG OutClibType(STRPTR);
  301. STRPTR GetClibType(STRPTR);    /* searches for next type definition */
  302. /* ------------------------------------------------------------------ */
  303. ULONG CallPrag(ULONG, STRPTR, ULONG (*) (struct AmiPragma *, ULONG));
  304. ULONG CreatePragmaFile(void);
  305. ULONG CreateLVOFile(ULONG);
  306. ULONG CreateAsmStubs(ULONG);
  307. ULONG CreateProtoFile(ULONG);
  308. ULONG CreateLocalData(void);
  309. /* ------------------------------------------------------------------ */
  310. ULONG GetName(struct NameList *, struct ShortListRoot *, ULONG);
  311. ULONG MakeFD(struct PragList *);
  312. void OptimizeFDData(struct PragData *);
  313. UBYTE GetHexValue(UBYTE);
  314. ULONG AddFDData(struct ShortListRoot *, struct FDData *);
  315. ULONG GetLibData(struct FDData *);
  316. ULONG GetAmiData(struct FDData *);
  317. ULONG CreateFDFile(STRPTR, STRPTR);
  318. /* ------------------------------------------------------------------ */
  319. void main(void);
  320. void end(void);
  321.  
  322. STRPTR strndup(STRPTR Str, ULONG Len)
  323. {
  324.   STRPTR res;
  325.   if((res = (STRPTR) AllocRemember(&remember, Len+1, MEMF_ANY|MEMF_CLEAR)))
  326.   {
  327.     CopyMem(Str, res, Len);
  328.     res[Len] = '\0';
  329.   }
  330.   return res;
  331. }
  332.  
  333. enum {
  334. ERR_TAGFUNC_NEEDS_ARGUMENT,
  335. ERR_CANNOT_CONVERT_PRAGMA_TAGCALL,
  336. ERR_TAG_DEF_WITHOUT_PRAGMA,
  337. ERR_BASENAME_DECLARED_TWICE,
  338. ERR_EXPECTED_SLASH_IN_BASENAME,
  339. ERR_EXPECTED_BASENAME,
  340. ERR_EXPECTED_BIAS_VALUE,
  341. ERR_ASSUMING_POSITIVE_BIAS_VALUE,
  342. ERR_MISSING_FUNCTION_NAME,
  343. ERR_EXPECTED_OPEN_BRACKET,
  344. ERR_TO_MUCH_ARGUMENTS,
  345. ERR_EXPECTED_ARGUMENT_NAME,
  346. ERR_EXPECTED_CLOSE_BRACKET,
  347. ERR_EXPECTED_REGISTER_NAME,
  348. ERR_ILLEGAL_REGISTER,
  349. ERR_REGISTER_USED_TWICE,
  350. ERR_AGUMENTNUMBER_DIFFERS_FROM_REGISTERNUMBER,
  351. ERR_ASSUMING_BIAS_OF_30,
  352. ERR_EXTRA_CHARACTERS,
  353. ERR_MISSING_BASENAME,
  354. ERR_WRITING_FILE,
  355. ERR_EXPECTED_COMMA,
  356. ERR_DIFFERENT_TO_PREVIOUS,
  357. ERR_UNKNOWN_VARIABLE_TYPE,
  358. ERR_UNKNOWN_ERROR,
  359. ERR_MISSING_END,
  360. };
  361.  
  362. struct ErrField {
  363.   UBYTE  Type;    /* 0 = Error, 1 = Warning */
  364.   UBYTE  Skip;
  365.   STRPTR Error;
  366. } Errors[] = {
  367. 1, 1, "Tag function must have arguments.",
  368. 1, 1, "Cannot convert pragma name into tag name.",
  369. 1, 1, "Tag definition without preceding Pragma.",
  370. 1, 0, "Basename declared twice.",
  371. 1, 0, "Expected preceding _ in Basename.",
  372. 1, 1, "Expected Basename.",
  373. 1, 0, "Expected Bias value.",
  374. 1, 0, "Assuming positive bias value.",
  375. 1, 1, "Missing function name.",
  376. 1, 1, "Expected '('.",
  377. 1, 1, "Too much arguments.",
  378. 1, 1, "Expected argument name.",
  379. 1, 1, "Expected ')'.",
  380. 1, 1, "Expected register name.",
  381. 1, 1, "A5 and A6 not allowed as argument register.",
  382. 1, 1, "Register used twice.",
  383. 1, 0, "Number of arguments != number of registers.",
  384. 1, 0, "Assuming bias of 30.",
  385. 1, 1, "Extra characters.",
  386. 0, 0, "Missing Basename.",
  387. 0, 0, "Failed to write destination file.",
  388. 1, 1, "Expected ','.",
  389. 1, 1, "Data different to previous given.",
  390. 1, 0, "Unknown type \"%s\", no C++ name for %s.",
  391. 0, 0, "Unknown problem: program error or corrupt input data.",
  392. 1, 0, "Missing ##end.",
  393. };
  394.  
  395. struct CPP_TypeField CPP_Field[] = {
  396. {"long",    4, 0,            CPP_TYPE_LONG},
  397. {"ULONG",    5, CPP_FLAG_UNSIGNED,    CPP_TYPE_LONG},
  398. {"LONGBITS",    8, CPP_FLAG_UNSIGNED,    CPP_TYPE_LONG},
  399. {"CPTR",    4, CPP_FLAG_UNSIGNED,    CPP_TYPE_LONG},
  400. {"Tag",     3, CPP_FLAG_UNSIGNED,    CPP_TYPE_LONG},
  401. {"Object",    6, CPP_FLAG_UNSIGNED,    CPP_TYPE_LONG},
  402. {"LONG",    4, 0,            CPP_TYPE_LONG},
  403. {"BPTR",    4, 0,            CPP_TYPE_LONG},
  404. {"BSTR",    4, 0,            CPP_TYPE_LONG},
  405. {"short",    5, 0,            CPP_TYPE_WORD},
  406. {"CxObj",    5, 0,            CPP_TYPE_LONG},
  407. {"CxMsg",    5, 0,            CPP_TYPE_LONG},
  408. {"USHORT",    6, CPP_FLAG_UNSIGNED,    CPP_TYPE_WORD},
  409. {"UWORD",    5, CPP_FLAG_UNSIGNED,    CPP_TYPE_WORD},
  410. {"UCOUNT",    6, CPP_FLAG_UNSIGNED,    CPP_TYPE_WORD},
  411. {"WORDBITS",    8, CPP_FLAG_UNSIGNED,    CPP_TYPE_WORD},
  412. {"RPTR",    4, CPP_FLAG_UNSIGNED,    CPP_TYPE_WORD},
  413. {"SHORT",    5, 0,            CPP_TYPE_WORD},
  414. {"COUNT",    5, 0,            CPP_TYPE_WORD},
  415. {"WORD",    4, 0,            CPP_TYPE_WORD},
  416. {"BOOL",    4, 0,            CPP_TYPE_WORD},
  417. {"char",    4, 0,            CPP_TYPE_BYTE},
  418. {"UBYTE",    5, CPP_FLAG_UNSIGNED,    CPP_TYPE_BYTE},
  419. {"TEXT",    4, CPP_FLAG_UNSIGNED,    CPP_TYPE_BYTE},
  420. {"BYTEBITS",    8, CPP_FLAG_UNSIGNED,    CPP_TYPE_BYTE},
  421. {"BYTE",    4, 0,            CPP_TYPE_BYTE},
  422. {"void",    4, 0,            CPP_TYPE_VOID},
  423. {"VOID",    4, 0,            CPP_TYPE_VOID},
  424. {"float",    5, 0,            CPP_TYPE_FLOAT},
  425. {"FLOAT",    5, 0,            CPP_TYPE_FLOAT},
  426. {"double",    6, 0,            CPP_TYPE_DOUBLE},
  427. {"DOUBLE",    6, 0,            CPP_TYPE_DOUBLE},
  428. {"STRPTR",    6, CPP_FLAG_POINTER|CPP_FLAG_STRPTR,    CPP_TYPE_BYTE},
  429. {"APTR",    4, CPP_FLAG_POINTER,    CPP_TYPE_VOID},
  430. {"ClassID",    7, CPP_FLAG_POINTER|CPP_FLAG_UNSIGNED,    CPP_TYPE_BYTE},
  431. {"PLANEPTR",    8, CPP_FLAG_POINTER|CPP_FLAG_UNSIGNED,    CPP_TYPE_BYTE},
  432. {"DisplayInfoHandle",17,CPP_FLAG_POINTER,CPP_TYPE_VOID},
  433. {0,0,0,0},
  434. };
  435.  
  436. struct Proto_LibTypes Proto_LibTypes[] = {
  437. {"DOSBase",            "DosLibrary"},
  438. {"SysBase",            "ExecBase"},
  439. {"ExpansionBase",        "ExpansionBase"},
  440. {"GfxBase",            "GfxBase"},
  441. {"IntuitionBase",        "IntuitionBase"},
  442. {"LocaleBase",            "LocaleBase"},
  443. {"MathIeeeDoubBasBase",     "MathIEEEBase"},
  444. {"MathIeeeDoubTransBase",    "MathIEEEBase"},
  445. {"MathIeeeSingBasBase",     "MathIEEEBase"},
  446. {"MathIeeeSingTransBase",    "MathIEEEBase"},
  447. {"RexxSysBase",         "RxsLib"},
  448. {"UtilityBase",         "UtilityBase"},
  449. /* non default Basenames */
  450. {"DatamasterBase",        "DatamasterBase"},
  451. {"PPBase",            "PPBase"},
  452. {"ReqToolsBase",        "ReqToolsBase"},
  453. {"UnpackBase",            "UnpackLibrary"},
  454. {"xfdMasterBase",        "xfdMasterBase"},
  455. {"GTXBase",            "GTXBase"},
  456. {0, 0},
  457. };
  458.  
  459. void DoError(UBYTE errnum, ULONG line, ...)
  460. {
  461.   STRPTR *arguments = (STRPTR *) (((STRPTR) &line) + sizeof(ULONG));
  462.   struct {
  463.     STRPTR type;
  464.     ULONG typenum;
  465.     ULONG linenum;
  466.   } args;
  467.  
  468.   args.type = Errors[errnum].Type ? "Warning" : "Error";
  469.   args.typenum = errnum;
  470.   args.linenum = line;
  471.  
  472.   VPrintf((line ? "%s %ld in line %ld: " : "%s %ld : "), &args);
  473.   VPrintf(Errors[errnum].Error, arguments);
  474.   PutStr("\n");
  475.   if(line && Errors[errnum].Skip)
  476.   {
  477.     while(*in.pos)
  478.       ++in.pos;
  479.   }
  480. }
  481.  
  482. ULONG Out(ULONG size)
  483. {
  484.   ULONG i = out.pos-out.buf;
  485.  
  486.   if(i && out.size - i <= size)
  487.   {
  488.     if(Write(out.file, out.buf, i) != i)
  489.     {
  490.       Output_Error = 0;
  491.       return 0;
  492.     }
  493.     out.count += i;
  494.     out.pos = out.buf;
  495.   }
  496.   return out.size;
  497. }
  498.  
  499. #ifdef __MAXON__
  500.   #define __asm
  501.   #define __saveds
  502.   #include <linkerfunc.h>
  503. #endif
  504.  
  505. static void __asm __saveds putfunc(register __d0 UBYTE data,
  506. register __a3 LONG *a)
  507. {
  508. #ifdef __MAXON__
  509.   GetBaseReg();
  510. #endif
  511.  
  512.   if(data)
  513.   {
  514.     if(!*a)
  515.       *a = Out(1);
  516.     if((*a)-- > 0)
  517.       *(out.pos++) = data;
  518.   }
  519. }
  520.  
  521. typedef void (*putchtype) ();
  522.  
  523. ULONG DoOutput(STRPTR format, ...)
  524. {
  525.   LONG a = out.buf+out.size-out.pos;
  526.  
  527.   if(!Output_Error)
  528.     return 0;
  529.  
  530.   RawDoFmt(format, (APTR) ((ULONG)&format+sizeof(STRPTR)),
  531.   (putchtype) putfunc, &a);
  532.  
  533.   if(a < 0)
  534.     return 0;
  535.   return 1;
  536. }
  537.  
  538. ULONG DoOutputDirect(APTR data, ULONG size)
  539. {
  540.   if(!Output_Error || !Out(size))
  541.     return 0;
  542.   CopyMem(data, out.pos, size);
  543.   out.pos += size;
  544.   return 1;
  545. }
  546.  
  547. STRPTR SkipBlanks(STRPTR OldPtr)
  548. {
  549.   while(*OldPtr == ' ' || *OldPtr == '\t')
  550.     ++OldPtr;
  551.   return OldPtr;
  552. }
  553.  
  554. /*
  555.     This function is used to skip over variable names.
  556.  
  557.     Inputs: OldPtr  - pointer to the beginning of a string.
  558.  
  559.     Result: Pointer to the first character of the string, that is not one
  560.         of a-z, A-Z, 0-9 or the underscore.
  561. */
  562.  
  563. STRPTR SkipName(STRPTR OldPtr)
  564. {
  565.   while(isalnum(*OldPtr) || *OldPtr == '_')
  566.     ++OldPtr;
  567.   return OldPtr;
  568. }
  569.  
  570. ULONG MakeTagFunction(struct AmiPragma *ap)
  571. {
  572.   ULONG len = strlen(ap->FuncName);
  573.  
  574. #ifdef DEBUG_OLD
  575.   VPrintf("MakeTagFunction:\n", 0);
  576. #endif
  577.  
  578.   ++tagfuncs;
  579.  
  580.   if(!strcmp(ap->FuncName, "VFWritef") ||
  581.   !strcmp(ap->FuncName, "VFPrintf") ||
  582.   !strcmp(ap->FuncName, "VPrintf"))
  583.   {
  584.     if(!(ap->TagName = strndup(ap->FuncName+1, len-1)))
  585.       return 0;
  586.   }
  587.   else if(ap->FuncName[len-1] == 'A')
  588.   {
  589.     if(!strcmp(ap->FuncName+len-3, "DMA"))
  590.     { --tagfuncs; return 1;}
  591.     if(!(ap->TagName = strndup(ap->FuncName, len-1)))
  592.       return 0;
  593.   }
  594.   else if(!strcmp(ap->FuncName + len-7, "TagList"))
  595.   {
  596.     if(!(ap->TagName = strndup(ap->FuncName, len-3)))
  597.       return 0;
  598.     ap->TagName[len-4] = 's';
  599.   }
  600.   else if(!strcmp(ap->FuncName + len-4, "Args"))
  601.   {
  602.     if(!strcmp(ap->FuncName, "ReadArgs") || !strcmp(ap->FuncName, "FreeArgs"))
  603.     { --tagfuncs;  return 1;}
  604.     if(!(ap->TagName = strndup(ap->FuncName, len-4)))
  605.       return 0;
  606.   }
  607.   else if(!stricmp(ap->Args[ap->NumArgs-1].ArgName, "tags") ||
  608.   !stricmp(ap->Args[ap->NumArgs-1].ArgName, "taglist"))
  609.   {
  610.     if(!(ap->TagName = strndup(ap->FuncName, len+4)))
  611.       return 0;
  612.     CopyMem("Tags", ap->TagName + len, 5);
  613.   }
  614.   else if(!stricmp(ap->Args[ap->NumArgs-1].ArgName, "args"))
  615.   {
  616.     if(!(ap->TagName = strndup(ap->FuncName, len+4)))
  617.       return 0;
  618.     CopyMem("Args", ap->TagName + len, 5);
  619.   }
  620.   else
  621.     --tagfuncs; /* not a tagfunction, incrementing was false, undo it */
  622.  
  623.   return 1;
  624. }
  625.  
  626. void MakeLines(STRPTR buffer, ULONG size, ULONG test)
  627. {
  628.   ULONG a = 0;
  629.   if(size && buffer)
  630.   {
  631.     /* make a real C++ zero string ending line */
  632.     while(--size)
  633.     {
  634.       switch(*buffer)
  635.       {
  636.       case '(': ++a; break;
  637.       case ')': --a; break;
  638.       case '\n':
  639.     if(!test || !a)
  640.       *buffer = '\0';
  641.     else
  642.       *buffer = ' ';
  643.     break;
  644.       }
  645.       ++buffer;
  646.     }
  647.     *buffer = '\0';
  648.   }
  649. }
  650.  
  651. ULONG ScanFDFile(void)
  652. {
  653. #ifdef DEBUG_OLD
  654.   VPrintf("ScanFDFile:\n", 0);
  655. #endif
  656.  
  657.   ULONG _public = 1;
  658.   LONG bias = -1;
  659.   ULONG linenum, len;
  660.   ULONG actcom = 0;
  661.  
  662.   for(linenum = 1; !CTRL_C && in.pos < in.buf + in.size; ++linenum)
  663.   {
  664.     if(*in.pos == '*')         /*  Comment   */
  665.     {
  666.       STRPTR oldpos = in.pos;
  667. #ifdef DEBUG_OLD
  668.   VPrintf("ScanFDFile: found a comment\n", 0);
  669. #endif
  670.       in.pos = SkipBlanks(in.pos+1);
  671.       if(!strnicmp(in.pos, "tagcall", 7))  /*  Tag to create?  */
  672.       {
  673.     struct AmiPragma *prevpragma = (struct AmiPragma *)
  674.         AmiPragma.Last;
  675.  
  676.     in.pos = SkipBlanks(in.pos + 7);
  677.     if(!prevpragma)
  678.     {
  679.       DoError(ERR_TAG_DEF_WITHOUT_PRAGMA, linenum);
  680.       ++in.pos;
  681.       continue;
  682.     }
  683.  
  684.     if(!prevpragma->NumArgs)
  685.     {
  686.       DoError(ERR_TAGFUNC_NEEDS_ARGUMENT, linenum);
  687.       ++in.pos;
  688.       continue;
  689.     }
  690.  
  691.     /* Get the tag functions name. */
  692.  
  693.     if(!prevpragma->TagName)
  694.       ++tagfuncs;
  695.  
  696.     if(*in.pos)
  697.     {
  698.       STRPTR oldptr, tptr = prevpragma->TagName;
  699.  
  700.       len = strlen(prevpragma->FuncName)+strlen(in.pos)+1;
  701.       if(!(prevpragma->TagName = strndup(prevpragma->FuncName, len)))
  702.         return 0;
  703.  
  704.       if(*in.pos == '-')
  705.       {
  706.         STRPTR removeptr;
  707.  
  708.         oldptr = in.pos = SkipBlanks(in.pos+1);
  709.         in.pos = SkipName(in.pos);
  710.         if((len = in.pos-oldptr))
  711.         {
  712.           removeptr = prevpragma->TagName+strlen(prevpragma->TagName)-len;
  713.           if(strncmp(removeptr, oldptr, len))
  714.           {
  715. #ifdef DEBUG_OLD
  716.         {
  717.           struct data {STRPTR a;STRPTR b;ULONG c;} a;
  718.           a.a = removeptr;
  719.           a.b = oldptr;
  720.           a.c = len;
  721.           VPrintf("ScanFDFile: *tagcall -: %s, %s, %ld\n", &a);
  722.         }
  723. #endif
  724.         DoError(ERR_CANNOT_CONVERT_PRAGMA_TAGCALL, linenum);
  725.         prevpragma->TagName = tptr;
  726.         ++in.pos;
  727.         continue;
  728.           }
  729.  
  730.           *removeptr = '\0';
  731.         }
  732.         in.pos = SkipBlanks(in.pos);
  733.       }
  734.       if(*in.pos == '+')
  735.         in.pos = SkipBlanks(in.pos+1);
  736.       else
  737.         *in.pos = toupper(*in.pos);
  738.  
  739.       in.pos = SkipName((oldptr = in.pos));
  740.       len = in.pos-oldptr;
  741.       if(len)
  742.       {
  743.         ULONG a = strlen(prevpragma->TagName);
  744.         CopyMem(oldptr, prevpragma->TagName+a, len);
  745.         prevpragma->TagName[a+len] = '\0';
  746.       }
  747.     }
  748.     else if(!prevpragma->TagName)
  749.     {
  750.       len = strlen(prevpragma->FuncName);
  751.       if(!(prevpragma->TagName = strndup(prevpragma->FuncName, len+4)))
  752.         return 0;
  753.       CopyMem("Tags", prevpragma->TagName + len, 5);
  754.     }
  755.       }
  756.       else
  757.       {
  758.     if(actcom)
  759.       *(oldpos-1) = '\n';
  760.     else if(Flags & FLAG_DOCOMMENT)
  761.     {
  762.       struct Comment *d;
  763.       if(!(d = (struct Comment *) NewItem(&Comment)))
  764.         return 0;
  765.       d->Bias = bias;
  766.       d->Data = oldpos;
  767.       AddItem(&Comment, (struct ShortList *) d);
  768.       actcom = 1;
  769.     }
  770.     while(*in.pos)
  771.       ++in.pos;
  772.       }
  773.     }
  774.     else if(!strnicmp(in.pos, "##base", 6))
  775.     {
  776. #ifdef DEBUG_OLD
  777.   VPrintf("ScanFDFile: found ##base\n", 0);
  778. #endif
  779.       STRPTR oldptr;
  780.  
  781.       actcom = 0; /* no Comment */
  782.  
  783.       if(BaseName)
  784.     DoError(ERR_BASENAME_DECLARED_TWICE, linenum);
  785.  
  786.       in.pos = SkipBlanks(in.pos+6);
  787.       if(*in.pos != '_')
  788.     DoError(ERR_EXPECTED_SLASH_IN_BASENAME, linenum);
  789.       else
  790.     ++in.pos;
  791.  
  792.       in.pos = SkipName((oldptr = in.pos));
  793.       if((len = in.pos-oldptr))
  794.       {
  795.     if(!(BaseName = strndup(oldptr, len)))
  796.       return 0;
  797.     if(!ShortBaseName && !(ShortBaseName = strndup(BaseName, len-4)))
  798.       return 0;
  799.  
  800.     if(!(ShortBaseNameUpper = strndup(ShortBaseName, strlen(ShortBaseName))))
  801.       return 0;
  802.     else
  803.     {
  804.       STRPTR a = ShortBaseNameUpper;
  805.       while((*a = toupper(*a)))    /* Convert to uppercase */
  806.         a++;
  807.     }
  808.       }
  809.       else
  810.     DoError(ERR_EXPECTED_BASENAME, linenum);
  811.     }
  812.     else if(!strnicmp(in.pos, "##bias", 6))
  813.     {
  814. #ifdef DEBUG_OLD
  815.   VPrintf("ScanFDFile: found ##bias\n", 0);
  816. #endif
  817.       STRPTR ptr;
  818.       LONG newbias;
  819.  
  820.       actcom = 0;
  821.  
  822.       in.pos += 7;
  823.       newbias = strtol(in.pos, &ptr, 10);
  824.       if(ptr == in.pos)
  825.     DoError(ERR_EXPECTED_BIAS_VALUE, linenum);
  826.       else if(newbias < 0)
  827.       {
  828.     DoError(ERR_ASSUMING_POSITIVE_BIAS_VALUE, linenum);
  829.     bias = -newbias;
  830.       }
  831.       else
  832.     bias = newbias;
  833.       in.pos = SkipName(in.pos);
  834.     }
  835.     else if(!strnicmp(in.pos, "##end", 5))
  836.     {
  837.       bias = 0; break;
  838.     }
  839.     else if(!strnicmp(in.pos, "##shadow", 8)) /* introduced by Storm */
  840.     {
  841.       actcom = 0;
  842.       in.pos += 8;
  843.       bias -= 6;
  844.     }
  845.     else if(!strnicmp(in.pos, "##public", 8))
  846.     {
  847.       actcom = 0;
  848.       in.pos += 8;
  849.       _public = 1;
  850.     }
  851.     else if(!strnicmp(in.pos, "##private", 9))
  852.     {
  853.       actcom = 0;
  854.       in.pos += 9;
  855.       _public = 0;
  856.     }
  857.     else
  858.     {
  859. #ifdef DEBUG_OLD
  860.   VPrintf("ScanFDFile: scan Function\n", 0);
  861. #endif
  862.       STRPTR oldptr;
  863.       struct AmiPragma ap;
  864.       ULONG numargs;
  865.  
  866.       memset(&ap, 0, sizeof(struct AmiPragma));
  867.       actcom = 0;
  868.  
  869.       oldptr = in.pos = SkipBlanks(in.pos);
  870.       in.pos = SkipName(oldptr);
  871.       if(!(len = in.pos-oldptr))
  872.       {
  873.     DoError(ERR_MISSING_FUNCTION_NAME, linenum);
  874.     ++in.pos;
  875.     continue;
  876.       }
  877.  
  878.       ap.FuncName = oldptr;
  879.  
  880.       in.pos = SkipBlanks(in.pos);
  881.       if(*in.pos != '(')
  882.       {
  883.     DoError(ERR_EXPECTED_OPEN_BRACKET, linenum);
  884.     ++in.pos;
  885.     continue;
  886.       }
  887.  
  888.       *in.pos = '\0'; /* create c string of FunctionName */
  889.  
  890. #ifdef DEBUG_OLD
  891.   VPrintf("ScanFDFile: found function %s\n", &ap.FuncName);
  892. #endif
  893.  
  894.       do
  895.       {
  896.     oldptr = in.pos = SkipBlanks(in.pos+1);
  897.  
  898.     if(*in.pos == ')' && !ap.NumArgs)
  899.       break;
  900.  
  901.     if(ap.NumArgs == 14)
  902.     {
  903.       DoError(ERR_TO_MUCH_ARGUMENTS, linenum); break;
  904.     }
  905.  
  906.     in.pos = SkipName(oldptr);
  907.     if(*in.pos == '*')
  908.       ++in.pos;
  909.     if(!(len = in.pos-oldptr))
  910.     {
  911.       DoError(ERR_EXPECTED_ARGUMENT_NAME, linenum);
  912.       break;
  913.     }
  914.  
  915.     ap.Args[ap.NumArgs++].ArgName = oldptr;
  916.     oldptr = in.pos;
  917.  
  918.     in.pos = SkipBlanks(in.pos);
  919.     if(*in.pos != ',' && *in.pos != '/' && *in.pos != ')')
  920.     {
  921.       DoError(ERR_EXPECTED_CLOSE_BRACKET, linenum);
  922.       break;
  923.     }
  924.     if(*in.pos != ')') /* create c string ending */
  925.       *oldptr = '\0';
  926.       }
  927.       while(*in.pos != ')');
  928.       if(*in.pos != ')')
  929.       {
  930.     while(*(in.pos++))
  931.       ++in.pos;
  932.     continue;
  933.       }
  934.       else
  935.     *oldptr = '\0'; /* create c string ending for last argument */
  936.     
  937.       if(*(in.pos = SkipBlanks(in.pos+1)) != '(')
  938.       {
  939.     DoError(ERR_EXPECTED_OPEN_BRACKET, linenum);
  940.     ++in.pos;
  941.     continue;
  942.       }
  943.  
  944.       numargs = 0;
  945.       do
  946.       {
  947.     ULONG i;
  948.  
  949.     oldptr = in.pos = SkipBlanks(in.pos + 1);
  950.  
  951.     if(*in.pos == ')' && numargs == 0)
  952.       break;
  953.  
  954.     in.pos = SkipName(oldptr);
  955.     len = in.pos-oldptr;
  956.  
  957.     for(i = 0; i < 16; i++)
  958.       if(!strnicmp(&RegNames[i<<2], oldptr, len))
  959.         break;
  960.  
  961.     if(i == 16)
  962.     {
  963.       DoError(ERR_EXPECTED_REGISTER_NAME, linenum);
  964.       break;
  965.     }
  966.     if(i > 14)
  967.     {
  968.       DoError(ERR_ILLEGAL_REGISTER, linenum);
  969.       break;
  970.     }
  971.  
  972.     ap.Args[numargs].ArgReg = i;
  973.  
  974.     for(i = 0; i < numargs; i++)
  975.     {
  976.       if(ap.Args[numargs].ArgReg == ap.Args[i].ArgReg)
  977.       {
  978.         DoError(ERR_REGISTER_USED_TWICE, linenum);
  979.         break;
  980.       }
  981.     }
  982.     if(i < numargs)
  983.       break;
  984.  
  985.     ++numargs;
  986.  
  987.     in.pos = SkipBlanks(in.pos);
  988.     if(*in.pos != ',' && *in.pos != '/' && *in.pos != ')')
  989.     {
  990.       DoError(ERR_EXPECTED_CLOSE_BRACKET, linenum);
  991.       break;
  992.     }
  993.       }
  994.       while(*in.pos != ')');
  995.       if(*in.pos != ')')
  996.       {
  997.     while(*(in.pos++))
  998.       ++in.pos;
  999.     continue;
  1000.       }
  1001.       else
  1002.     ++in.pos;
  1003.  
  1004.       if(Flags & FLAG_STORMFD)
  1005.       {
  1006.     if(!strcmp(ap.Args[ap.NumArgs-1].ArgName, "tags"))
  1007.     {
  1008.       ap.TagName = ap.FuncName;
  1009.       ap.FuncName = 0;
  1010.       ++tagfuncs;
  1011. #ifdef DEBUG_OLD
  1012.       VPrintf("ScanFDFile: StormFD mode, tag func: %s\n", &ap.TagName);
  1013. #endif
  1014.     }
  1015. #ifdef DEBUG_OLD
  1016.     else
  1017.     {
  1018.       STRPTR a[2];
  1019.       a[0] = ap.FuncName;
  1020.       a[1] = ap.Args[ap.NumArgs-1].ArgName;
  1021.       VPrintf("ScanFDFile: StormFD mode, normal func: %s(..., %s)\n", &a);
  1022.     }
  1023. #endif
  1024.       }
  1025.       else if(!MakeTagFunction(&ap))
  1026.     return 0;
  1027.  
  1028.       if(numargs != ap.NumArgs)
  1029.       {
  1030.     DoError(ERR_AGUMENTNUMBER_DIFFERS_FROM_REGISTERNUMBER, linenum);
  1031.     ap.NumArgs = numargs;
  1032.       }
  1033.  
  1034.       if(bias == -1)
  1035.       {
  1036.     DoError(ERR_ASSUMING_BIAS_OF_30, linenum);
  1037.     bias = 30;
  1038.       }
  1039.       ap.Bias = bias;
  1040.       bias += 6;
  1041.  
  1042.       ap.Public = _public;
  1043.  
  1044.       {
  1045.     struct AmiPragma *d;
  1046.     if(!(d = (struct AmiPragma *) NewItem(&AmiPragma)))
  1047.       return 0;
  1048.     CopyMem(&ap, d, sizeof(struct AmiPragma));
  1049.     AddItem(&AmiPragma, (struct ShortList *) d);
  1050.       }
  1051.     }
  1052.  
  1053.     in.pos = SkipBlanks(in.pos);
  1054.     if(*in.pos)
  1055.       DoError(ERR_EXTRA_CHARACTERS, linenum);
  1056.     ++in.pos; /* skip '\0' */
  1057.   }
  1058.  
  1059.   if(CTRL_C)
  1060.     return 0;
  1061.  
  1062.   if(!BaseName)
  1063.   {
  1064.     DoError(ERR_MISSING_BASENAME, 0); return 0;
  1065.   }
  1066.   else if(bias)
  1067.     DoError(ERR_MISSING_END, 0);
  1068.  
  1069.   return 1;
  1070. }
  1071.  
  1072. void FindHeader(void)
  1073. {
  1074.   STRPTR str = HEADER;
  1075.   ULONG mode = 0;
  1076.  
  1077.   do
  1078.   {
  1079.     if(!mode)
  1080.       HEADER = str;
  1081.  
  1082.     if(*str == '/')
  1083.     {
  1084.       ++str;
  1085.       if(*str == '*')
  1086.       {
  1087.     mode = 2; break;
  1088.       }
  1089.       else if(*str == '/')
  1090.     mode = 1;
  1091.     }
  1092.     else if(*str == '*' || *str == ';')
  1093.       mode = 1;
  1094.     else if(mode)
  1095.       break;
  1096.     while(*str && *(str++) != '\n')
  1097.       ;
  1098.   } while(*str);
  1099.  
  1100.   if(mode == 2)
  1101.   {
  1102.     while(*str && (*(str-1) != '*' || *str != '/'))
  1103.       ++str;
  1104.     while(*str && *(str++) != '\n')
  1105.       ;
  1106.   }
  1107.    
  1108.   if(mode)
  1109.     headersize = str-HEADER;
  1110.   else
  1111.   {
  1112.     HEADER = 0; headersize = 0;
  1113.   }
  1114. }
  1115.  
  1116. /* returns decrement data in bits 0-15 and increment data in bits 16-31 */
  1117. ULONG GetRegisterData(struct AmiPragma *ap)
  1118. {
  1119. /* usage of result:
  1120.     48E7 <lower word>    MOVEM.L <registers>,-(A7) ; D0 is bit 15
  1121.     4CDF <upper word>    MOVEM.L (A7)+,<registers> ; D0 is bit 0
  1122. */
  1123.   register ULONG i, data = 0, reg;
  1124.  
  1125.   for(i = 0; i < ap->NumArgs; ++i)
  1126.   {
  1127.     reg = ap->Args[i].ArgReg;
  1128.  
  1129.     if(reg >= 10 || (reg >= 2 &&  reg <= 7)) /* A2-A7 and D2-D7 */
  1130.       data |= (1 << (reg + 16)) + (1 << (15 - reg));
  1131.   }
  1132.   if(data)    /* set A6 only when other register used */
  1133.     data |= 0x40000002;
  1134.   return data;
  1135. }
  1136.  
  1137. static void __asm __saveds xdefputfunc(register __d0 UBYTE data,
  1138. register __a3 STRPTR *a)
  1139. {
  1140.   *((*a)++) = data;
  1141. }
  1142.  
  1143. ULONG OutputXDEF(STRPTR format, ...)
  1144. {
  1145.   UBYTE b[150];
  1146.   STRPTR c = b + 4;
  1147.   UWORD i;
  1148.  
  1149.   memset(b, 0, 150);
  1150.   RawDoFmt(format, (APTR) ((ULONG)&format+sizeof(STRPTR)),
  1151.   (putchtype) xdefputfunc, &c);
  1152.   /* c now holds pointer to end */
  1153.   i = (c-(b+4)+2)>>2;
  1154.   *((ULONG *) b) = 0x01000000 + i;
  1155.  
  1156.   return DoOutputDirect(b, (i+2)<<2);
  1157. }
  1158.  
  1159. /* ------------------------------------------------------------------ */
  1160.  
  1161. struct ShortList *NewItem(struct ShortListRoot *list)
  1162. {
  1163.   struct ShortList *item;
  1164.   if(!list || !list->Size)
  1165.     return 0;
  1166.   if(!(item = (struct ShortList *) AllocRemember(&remember, list->Size,
  1167.   MEMF_ANY|MEMF_CLEAR)))
  1168.     return 0;
  1169.   return item;
  1170. }
  1171.  
  1172. struct ShortList *RemoveItem(struct ShortListRoot *list, struct ShortList *item)
  1173. {
  1174.   struct ShortList *n = list->First;
  1175.  
  1176.   if(n == item)
  1177.     list->First = item->Next;
  1178.   else
  1179.   {
  1180.     while(n && n->Next != item)
  1181.       n = n->Next;
  1182.     if(!n)
  1183.       return 0;
  1184.     if(!(n->Next = item->Next))
  1185.       list->Last = n;
  1186.   }
  1187.   item->Next = 0;
  1188.   return item;
  1189. }
  1190.  
  1191. void AddItem(struct ShortListRoot *list, struct ShortList *item)
  1192. {
  1193.   if(!list->First)
  1194.     list->First = list->Last = item;
  1195.   else
  1196.   {
  1197.     list->Last->Next = item;
  1198.     list->Last = item;
  1199.   }
  1200. }
  1201.  
  1202. /* ------------------------------------------------------------------ */
  1203.  
  1204. ULONG FuncAMICALL(struct AmiPragma *Ap, ULONG tagmode)
  1205. {
  1206.   ULONG i;
  1207.  
  1208.   DoOutput("#pragma %s(%s,0x%03lx,%s("/*))*/, tagmode ? "tagcall" :
  1209.   "amicall", BaseName, Ap->Bias, tagmode ? Ap->TagName : Ap->FuncName);
  1210.  
  1211.   for(i = 0; i < Ap->NumArgs; ++i)
  1212.   {
  1213.     DoOutput(&RegNames[(Ap->Args[i].ArgReg)<<2]);
  1214.     if(i+1 < Ap->NumArgs)
  1215.       DoOutput(",");
  1216.   }
  1217.  
  1218.   return DoOutput(/*((*/"))\n");
  1219. }
  1220.  
  1221. ULONG FuncLIBCALL(struct AmiPragma *Ap, ULONG tagmode)
  1222. {
  1223.   LONG i;
  1224.  
  1225.   if((Flags & FLAG_SYSCALL) && !strcmp(BaseName,"SysBase"))
  1226.     DoOutput("#pragma syscall %-20s %03lx ", Ap->FuncName, Ap->Bias);
  1227.   else
  1228.     DoOutput("#pragma %s %s %-20s %03lx ", tagmode ? "tagcall" :
  1229.     "libcall", BaseName, tagmode ? Ap->TagName : Ap->FuncName, Ap->Bias);
  1230.  
  1231.   for(i = Ap->NumArgs-1; i >= 0; --i)
  1232.     DoOutput("%lx",Ap->Args[i].ArgReg);
  1233.  
  1234.   return DoOutput("0%lx\n", Ap->NumArgs);
  1235. }
  1236.  
  1237. ULONG FuncAsmText(struct AmiPragma *ap, ULONG tagmode)
  1238. {
  1239.   STRPTR text = tagmode ? ap->TagName : ap->FuncName, a;
  1240.   LONG i;
  1241.   ULONG registers;
  1242.   ULONG offset = 1;
  1243.  
  1244.   DoOutput("\n\tXDEF\t_%s\n_%s:\n",text, text);
  1245.   if(!(Flags & FLAG_PASCAL))
  1246.   {
  1247.     DoOutput("\n\tXDEF\t%s\n%s:\n",text, text);
  1248.     if(!ap->NumArgs && clibbuf)
  1249.       DoOutput("\tXDEF\t%s_\n%s_:\n",text, text);
  1250.     else if((a = FindClibFunc(text)))
  1251.     {
  1252.       UBYTE name[300];
  1253.       ULONG ret = 0;
  1254.  
  1255.       do
  1256.       {
  1257.     if((ret = CopyCPPType(name, a, ret, text, ap->Args)))
  1258.       DoOutput("\tXDEF\t%s__%s\n%s__%s:\n",text, name, text, name);
  1259.       } while(ret == 0xFFFFFFFF);
  1260.     }
  1261.   }
  1262.  
  1263.   if((registers = GetRegisterData(ap) >> 16))
  1264.   {
  1265.     UWORD l = registers;
  1266.  
  1267.     DoOutput("\tMOVEM.L\t");
  1268.  
  1269.     for(i = 0; i <= 15; ++i)
  1270.     {
  1271.       if(l & (1 << i))
  1272.       {
  1273.     ++offset;
  1274.     l ^= 1 << i;
  1275.     DoOutput(&RegNames[i<<2]);
  1276.     if(l)
  1277.       DoOutput("/");
  1278.       }
  1279.     }
  1280.     DoOutput(",-(A7)\n");
  1281.   }
  1282.   else
  1283.   {
  1284.     DoOutput("\tMOVE.L\tA6,-(A7)\n"); ++offset;
  1285.   }
  1286.  
  1287.   DoOutput("\tMOVE.L\t_%s,A6\n", BaseName);
  1288.  
  1289.   if(!(Flags & FLAG_PASCAL))
  1290.   {
  1291.     for(i = 0; i < ap->NumArgs - (tagmode ? 1 : 0); ++i)
  1292.       DoOutput("\tMOVE.L\t%02ld(A7),%s\n", (i+offset)<<2,
  1293.       &RegNames[(ap->Args[i].ArgReg)<<2]);
  1294.  
  1295.     if(i < ap->NumArgs)
  1296.     {
  1297.       if(ap->Args[i].ArgReg > 7)
  1298.     DoOutput("\tLEA\t%02ld(A7),%s\n", (i+offset)<<2,
  1299.     &RegNames[(ap->Args[i].ArgReg)<<2]);
  1300.       else
  1301.     DoOutput("\tMOVE.L\tA7,%s\n\tADD%s.L\t#%02ld,%s\n",
  1302.     &RegNames[(ap->Args[i].ArgReg)<<2], (i + offset <= 2 ? "Q" : ""),
  1303.     (i+offset)<<2, &RegNames[(ap->Args[i].ArgReg)<<2]);
  1304.     }
  1305.   }
  1306.   else
  1307.   {
  1308.     for(i = 0; i < ap->NumArgs; ++i)
  1309.       DoOutput("\tMOVE.L\t%02ld(A7),%s\n", (ap->NumArgs-(i+1)+offset)<<2,
  1310.       &RegNames[(ap->Args[i].ArgReg)<<2]);
  1311.   }
  1312.  
  1313.   DoOutput("\tJSR\t-%03ld(A6)\n",ap->Bias);
  1314.  
  1315.   if(registers)
  1316.   {
  1317.     DoOutput("\tMOVEM.L\t(A7)+,");
  1318.  
  1319.     for(i = 0; i <= 15; ++i)
  1320.     {
  1321.       if(registers & (1 << i))
  1322.       {
  1323.     registers ^= 1 << i;
  1324.     DoOutput(&RegNames[i<<2]);
  1325.     if(registers)
  1326.       DoOutput("/");
  1327.       }
  1328.     }
  1329.     DoOutput("\n");
  1330.   }
  1331.   else
  1332.     DoOutput("\tMOVE.L\t(A7)+,A6\n");
  1333.  
  1334.   return DoOutput("\tRTS\n");
  1335. }
  1336.  
  1337. ULONG FuncAsmCode(struct AmiPragma *ap, ULONG tagmode)
  1338. {
  1339.   ULONG registers;
  1340.   STRPTR text = tagmode ? ap->TagName : ap->FuncName, str;
  1341.   ULONG a[5];
  1342.   ULONG offset = 1;
  1343.   LONG i = strlen(ShortBaseNameUpper);
  1344.  
  1345.   registers = GetRegisterData(ap);
  1346.  
  1347.   a[0] = HUNK_UNIT; a[1] = 0; a[2] = HUNK_NAME;
  1348.   a[3] = (i + 6 + 3)>>2;
  1349.  
  1350.   DoOutputDirect(a, 16);
  1351.   DoOutputDirect(ShortBaseNameUpper, i);
  1352.   DoOutputDirect("_STUBS\0\0\0", (a[3]<<2)-i);
  1353.  
  1354.   a[0] = HUNK_CODE; a[1] = ap->NumArgs + (registers ? 5 : 4);
  1355.  
  1356.   if(tagmode && ap->NumArgs > 1 && ap->Args[ap->NumArgs-1].ArgReg <= 7)
  1357.     ++a[1];    /* one longword more, when D register and tagcall */
  1358.  
  1359.   DoOutputDirect(a, 8);
  1360.  
  1361.   a[0] = 0x2F0E2C79, a[1] = 0;
  1362.  
  1363.   if(registers)
  1364.   {
  1365.     UWORD l = 0x48E7;
  1366.     a[0] = (registers << 16) + 0x2C79;
  1367.     DoOutputDirect(&l, 2);
  1368.     for(l = (UWORD) registers; l; l >>= 1)
  1369.     {
  1370.       if(l & 1)
  1371.     ++offset;
  1372.     }
  1373.   }
  1374.   else
  1375.     ++offset;
  1376.  
  1377.   DoOutputDirect(a, 8);
  1378.  
  1379.   if(!(Flags & FLAG_PASCAL))
  1380.   {
  1381.     for(i = 0; i < ap->NumArgs - (tagmode ? 1 : 0); ++i) /* generate MOVE.L code */
  1382.     {
  1383.       ULONG j;
  1384.  
  1385.       a[0] = 0x202F0000 + ((i+offset)<<2);
  1386.  
  1387.       j = ap->Args[i].ArgReg;
  1388.       if(j > 7)
  1389.       {
  1390.     a[0] |= 0x400000; j -= 8;    /* set MOVEA bit */
  1391.       }
  1392.       a[0] |= j << 25;        /* set destination register */
  1393.  
  1394.       DoOutputDirect(a, 4);
  1395.     }
  1396.  
  1397.     if(i < ap->NumArgs)
  1398.     {
  1399.       ULONG j = ap->Args[i].ArgReg;
  1400.       if(j > 7)
  1401.       {             /* LEA x(A7),Ax */
  1402.     a[0] = (0x41EF0000 | ((j-8) << 25)) + ((i+offset) << 2);
  1403.       }
  1404.       else if(i+offset == 2)
  1405.       {             /* MOVE.L A7,Dx  -- ADDQ.L #8,Dx */
  1406.     a[0] = 0x200F5080 | j | (j << 25);
  1407.       }
  1408.       else
  1409.       {             /* MOVE.L A7,Dx  -- ADD.L #x,Dx */
  1410.     a[0] = 0x200FD0BC | (j << 25) | (j<<9);
  1411.     a[1] = (i+offset) << 2;
  1412.       }
  1413.  
  1414.       DoOutputDirect(a, (i + offset != 2 && j <= 7) ? 8 : 4);
  1415.     }
  1416.   }
  1417.   else
  1418.   {
  1419.     for(i = 0; i < ap->NumArgs; ++i) /* generate MOVE.L code */
  1420.     {
  1421.       ULONG j;
  1422.  
  1423.       a[0] = 0x202F0000 + ((ap->NumArgs-(i+1)+offset)<<2);
  1424.  
  1425.       j = ap->Args[i].ArgReg;
  1426.       if(j > 7)
  1427.       {
  1428.     a[0] |= 0x400000; j -= 8;    /* set MOVEA bit */
  1429.       }
  1430.       a[0] |= j << 25;        /* set destination register */
  1431.  
  1432.       DoOutputDirect(a, 4);
  1433.     }
  1434.   }
  1435.  
  1436.   /* here comes the base reference */
  1437.   a[0] = 0x4EAE0000 + (UWORD) (- ap->Bias); /* JSR instruction */
  1438.  
  1439.   DoOutputDirect(a, 4);
  1440.  
  1441.   if(registers)
  1442.   {
  1443.     a[0] = 0x4CDF0000 + (registers >> 16);
  1444.     a[1] = 0x4E750000;
  1445.     DoOutputDirect(a, 6);
  1446.   }
  1447.   else
  1448.   {
  1449.     a[0] = 0x2C5F4E75;
  1450.     DoOutputDirect(a, 4);
  1451.   }
  1452.  
  1453.   a[0] = HUNK_EXT;
  1454.   a[1] = 0x81000000 + ((strlen(BaseName) + 1 + 3)>>2);
  1455.   a[2] = 0x5F000000;
  1456.  
  1457.   DoOutputDirect(a, 9);
  1458.   DoOutputDirect(BaseName, (((UWORD) a[1])<<2)-1);
  1459.  
  1460.   a[0] = 1; a[1] = (registers ? 6 : 4);
  1461.   DoOutputDirect(a, 8);
  1462.  
  1463.   /* here come the XDEF name references */
  1464.   OutputXDEF("_%s", text);        /* C name */
  1465.  
  1466.   if(!(Flags & FLAG_PASCAL))
  1467.   {
  1468.     OutputXDEF("%s", text);        /* ASM name */
  1469.  
  1470.     if(!ap->NumArgs && clibbuf)
  1471.       OutputXDEF("%s_", text);        /* C++ name no parameters */
  1472.     else if((str = FindClibFunc(text)))
  1473.     {
  1474.       UBYTE name[100];
  1475.       ULONG ret = 0;
  1476.  
  1477.       do
  1478.       {
  1479.     if((ret = CopyCPPType(name, str, ret, text, ap->Args)))
  1480.       OutputXDEF("%s__%s", text, name); /* C++ name with parameters */
  1481.       } while(ret == 0xFFFFFFFF);
  1482.     }
  1483.   }
  1484.  
  1485.   a[0] = 0; a[1] = HUNK_END;
  1486.  
  1487.   return DoOutputDirect(a, 8);
  1488. }
  1489.  
  1490. ULONG FuncCSTUBS(struct AmiPragma *ap, ULONG TagCall)
  1491. {
  1492.   STRPTR string,str2,lastarg;
  1493.   STRPTR ret = "return ";
  1494.   ULONG i;
  1495.  
  1496.   str2 = FindClibFunc(ap->TagName);
  1497.   if(!(string = FindClibFunc(ap->FuncName)))
  1498.     string = deftype;
  1499.  
  1500.   string = SkipBlanks(string);
  1501.   if(!strnicmp("void", string, 4))
  1502.     ret = 0;
  1503.  
  1504.   if(!OutClibType(string) || !DoOutput(" %s("/*)*/, ap->TagName))
  1505.     return 0;
  1506.   for(i = 0; i < ap->NumArgs-1; i++)
  1507.   {
  1508.     str2 = GetClibType(str2);        /* skip the equal parts */
  1509.     if(!(string = GetClibType(string)) || !OutClibType(string) ||
  1510.     !DoOutput(" %s, ", ap->Args[i].ArgName))
  1511.       return 0;
  1512.   }
  1513.   lastarg = string;
  1514.   if((str2 = GetClibType(str2)))
  1515.   {
  1516.     if(!strncmp("...", str2, 3))
  1517.       str2 = 0;
  1518.     else if(!OutClibType(str2) || !DoOutput(" %s, ", ap->Args[i].ArgName))
  1519.       return 0;
  1520.   }
  1521.   else if(ap->NumArgs == 1 && !DoOutput("ULONG tag, "))
  1522.     return 0;
  1523.  
  1524.   if(!DoOutput(/*(*/"...)\n{\n  %s%s("/*)*/, ret, ap->FuncName))
  1525.     return 0;
  1526.   for(i = 0; i < ap->NumArgs-1; i++)
  1527.   {
  1528.     if(!DoOutput("%s, ", ap->Args[i].ArgName))
  1529.       return 0;
  1530.   }
  1531.   if(!DoOutput("("/*)*/) || !(string = GetClibType(string)) ||
  1532.   !OutClibType(string))
  1533.     return 0;
  1534.   if(str2)
  1535.   {
  1536.     if(!DoOutput(/*((*/") &%s);\n}\n", ap->Args[ap->NumArgs-1].ArgName))
  1537.       return 0;
  1538.   }
  1539.   else if(ap->NumArgs == 1)
  1540.   {
  1541.     if(!DoOutput(/*((*/") &tag);\n}\n"))
  1542.       return 0;
  1543.   }
  1544.   else if (!DoOutput(/*(*/") ((ULONG) &%s + sizeof("/*))*/,
  1545.   ap->Args[ap->NumArgs-2].ArgName) || !OutClibType(lastarg) ||
  1546.   !DoOutput(/*(((*/")));\n}\n"))
  1547.     return 0;
  1548.   return 1;
  1549. }
  1550.  
  1551. ULONG FuncLVOXDEF(struct AmiPragma *ap, ULONG data)
  1552. {
  1553.   return DoOutput("\t\tXDEF\t_LVO%s\n", ap->FuncName);
  1554. }
  1555.  
  1556. ULONG FuncLVO(struct AmiPragma *ap, ULONG data)
  1557. {
  1558.   return DoOutput("\n_LVO%-24s\tEQU\t-%ld", ap->FuncName, ap->Bias);
  1559. }
  1560.  
  1561. ULONG FuncLocCode(struct AmiPragma *ap, ULONG tagmode)
  1562. {
  1563.   ULONG a[5];
  1564.   STRPTR text = tagmode ? ap->TagName : ap->FuncName, str,
  1565.      str2 = Flags & FLAG_LOCALREG ? "rE" : "";
  1566.   LONG i = strlen(ShortBaseNameUpper);
  1567.   ULONG j;
  1568.  
  1569.   a[0] = HUNK_UNIT; a[1] = 0; a[2] = HUNK_NAME;
  1570.   a[3] = (i + 4 + 3)>>2;
  1571.  
  1572.   DoOutputDirect(a, 16);
  1573.   DoOutputDirect(ShortBaseNameUpper, i);
  1574.   DoOutputDirect("_LOC\0\0\0", (a[3]<<2)-i);
  1575.  
  1576.   if(Flags & FLAG_LOCALREG)
  1577.   {
  1578.     if(tagmode)
  1579.     {
  1580.       j = ap->Args[ap->NumArgs-1].ArgReg;
  1581.       a[0] = HUNK_CODE; a[1] = 4;
  1582.       a[2] = 0x2F000000 + (j << 16);    /* MOVE <ea>,-(A7) */
  1583.  
  1584.       DoOutputDirect(a, 10);
  1585.  
  1586.       a[1] = 0x4EAE0000 + (UWORD) (- ap->Bias); /* JSR instruction */
  1587.       a[2] = 0x201F4E75;        /* MOVE (A7)+,<ea> */
  1588.       a[3] = 0;
  1589.       if(j > 7)
  1590.       {                 /* LEA x(A7),Ax */
  1591.     j -= 8;
  1592.     a[0] = 0x41EF0008 | (j << 25);
  1593.     a[2] += 0x400000;        /* set A flag */
  1594.       }
  1595.       else
  1596.       {                 /* MOVE.L A7,Dx  -- ADDQ.L #8,Dx */
  1597.     a[0] = 0x200F5080 | j | (j << 25);
  1598.       }
  1599.       a[2] += j << 25;
  1600.       
  1601.       DoOutputDirect(a, 14);
  1602.     }
  1603.     else
  1604.     {
  1605.       a[0] = HUNK_CODE; a[1] = 1;
  1606.       a[2] = 0x4EEE0000 + (UWORD) (- ap->Bias); /* JMP instruction */
  1607.       DoOutputDirect(a, 12);
  1608.     }
  1609.   }
  1610.   else
  1611.   {
  1612.     ULONG registers;
  1613.     ULONG offset = 1;
  1614.  
  1615.     registers = GetRegisterData(ap) | 0x40000002;
  1616.  
  1617.     a[0] = HUNK_CODE; a[1] = ap->NumArgs + 5;
  1618.  
  1619.     if(tagmode && ap->Args[ap->NumArgs-1].ArgReg <= 7)
  1620.       ++a[1];    /* one longword more, when D register and tagcall */
  1621.  
  1622.     DoOutputDirect(a, 8);
  1623.  
  1624.     a[0] = 0x48E70000 + (registers & 0xFFFF);
  1625.     for(j = (UWORD) registers; j; j >>= 1)
  1626.     {
  1627.       if(j & 1)
  1628.     ++offset;
  1629.     }
  1630.     a[1] = 0x2C6F0000+ ((offset++)<<2);
  1631.     DoOutputDirect(a, 8);
  1632.  
  1633.     for(i = 0; i < ap->NumArgs - (tagmode ? 1 : 0); ++i) /* generate MOVE.L code */
  1634.     {
  1635.       a[0] = 0x202F0000 + ((i+offset)<<2);
  1636.  
  1637.       j = ap->Args[i].ArgReg;
  1638.       if(j > 7)
  1639.       {
  1640.     a[0] |= 0x400000; j -= 8;    /* set MOVEA bit */
  1641.       }
  1642.       a[0] |= j << 25;            /* set destination register */
  1643.  
  1644.       DoOutputDirect(a, 4);
  1645.     }
  1646.  
  1647.     if(i < ap->NumArgs)
  1648.     {
  1649.       if((j = ap->Args[i].ArgReg) > 7)
  1650.       {                 /* LEA x(A7),Ax */
  1651.     a[0] = (0x41EF0000 | ((j-8) << 25)) + ((i+offset) << 2);
  1652.       }
  1653.       else
  1654.       {                 /* MOVE.L A7,Dx  -- ADD.L #x,Dx */
  1655.     a[0] = 0x200FD0BC | (j << 25) | (j<<9);
  1656.     a[1] = (i+offset) << 2;
  1657.       }
  1658.  
  1659.       DoOutputDirect(a, j <= 7 ? 8 : 4);
  1660.     }
  1661.  
  1662.     /* here comes the base reference */
  1663.     a[0] = 0x4EAE0000 + (UWORD) (- ap->Bias); /* JSR instruction */
  1664.  
  1665.     DoOutputDirect(a, 4);
  1666.  
  1667.     a[0] = 0x4CDF0000 + (registers >> 16);
  1668.     a[1] = 0x4E750000;
  1669.     DoOutputDirect(a, 8);
  1670.   }
  1671.  
  1672.   a[0] = HUNK_EXT;
  1673.   DoOutputDirect(a,4);
  1674.  
  1675.   /* here come the XDEF name references */
  1676.  
  1677.   OutputXDEF("%s", text);    /* ASM names */
  1678.   OutputXDEF("LOC_%s", text);
  1679.  
  1680.   OutputXDEF("_%s", text);    /* C names */
  1681.   OutputXDEF("_LOC_%s", text);
  1682.  
  1683.   if(!ap->NumArgs && clibbuf)
  1684.   {
  1685.     OutputXDEF("%s_%sP07Library", text, str2);    /* C++ names no parameters */
  1686.     OutputXDEF("LOC_%s__%sP07Library", text, str2);
  1687.   }
  1688.   else if((str = FindClibFunc(text)))
  1689.   {
  1690.     UBYTE name[100];
  1691.     ULONG ret = 0;
  1692.  
  1693.     do
  1694.     {
  1695.       if((ret = CopyCPPType(name, str, ret, text, ap->Args)))
  1696.       {                 /* C++ names with parameters */
  1697.     OutputXDEF("%s__%sP07Library%s", text, str2, name);
  1698.     OutputXDEF("LOC_%s__%sP07Library%s", text, str2, name);
  1699.       }
  1700.     } while(ret == 0xFFFFFFFF);
  1701.   }
  1702.  
  1703.   a[0] = 0; a[1] = HUNK_END;
  1704.  
  1705.   return DoOutputDirect(a, 8);
  1706. }
  1707.  
  1708. ULONG FuncLocText(struct AmiPragma *ap, ULONG tagmode)
  1709. {
  1710.   STRPTR text = tagmode ? ap->TagName : ap->FuncName;
  1711.   STRPTR string;
  1712.   LONG i;
  1713.  
  1714.   if(!(string = FindClibFunc(text)))
  1715.     string = deftype;
  1716.  
  1717.   string = SkipBlanks(string);
  1718.  
  1719.   OutClibType(string);
  1720.   DoOutput(" LOC_%s("/*)*/, text);
  1721.   if(Flags & FLAG_LOCALREG)
  1722.     DoOutput("register __a6 ");
  1723.   DoOutput("struct Library * libbase");
  1724.   if(ap->NumArgs)
  1725.   {
  1726.     DoOutput(", ");
  1727.  
  1728.     for(i = 0; i < ap->NumArgs-1; i++)
  1729.     {
  1730.       if(!(string = GetClibType(string)) ||
  1731.       ((Flags & FLAG_LOCALREG &&
  1732.       !DoOutput("register __%s ", &RegNames[(ap->Args[i].ArgReg)<<2]))) ||
  1733.       !OutClibType(string) || !DoOutput(" %s, ", ap->Args[i].ArgName))
  1734.     return 0;
  1735.     }
  1736.  
  1737.     if(!tagmode)
  1738.     {
  1739.       if(!(string = GetClibType(string)) ||
  1740.       ((Flags & FLAG_LOCALREG &&
  1741.       !DoOutput("register __%s ", &RegNames[(ap->Args[i].ArgReg)<<2]))) ||
  1742.       !OutClibType(string) ||
  1743.       !DoOutput(/*(*/" %s);\n#define %s("/*)*/, ap->Args[i].ArgName, text))
  1744.     return 0;
  1745.       for(i = 0; i < ap->NumArgs-1; ++i)
  1746.     DoOutput("%lc, ", (i+'a'));
  1747.       DoOutput(/*(*/"%lc) LOC_%s((struct Library *) %s, "/*)*/,(i+'a'),
  1748.       text, BaseName);
  1749.       for(i = 0; i < ap->NumArgs-1; ++i)
  1750.     DoOutput("%lc, ",(i+'a'));
  1751.       return DoOutput(/*(*/"%lc)\n\n",(i+'a'));
  1752.     }
  1753.     else
  1754.       return DoOutput(/*(*/"...);\n");
  1755.   }
  1756.   else
  1757.     return DoOutput(/*(*/");\n");
  1758. }
  1759.  
  1760. ULONG CallFunc(ULONG tagmode, STRPTR comment,
  1761. ULONG (*Func) (struct AmiPragma *, ULONG))
  1762. {
  1763.   struct Comment *com = 0;
  1764.   struct AmiPragma *ap;
  1765.  
  1766.   if(comment)
  1767.     com = (struct Comment *) Comment.First;
  1768.  
  1769.   for(ap = (struct AmiPragma *) AmiPragma.First; ap && !CTRL_C;
  1770.   ap = (struct AmiPragma *) ap->List.Next)
  1771.   {
  1772.     if(ap->Public || (Flags & FLAG_PRIVATE))
  1773.     {
  1774.       while(com && com->Bias <= ap->Bias)
  1775.       {
  1776.     if(!DoOutput(comment, com->Data))
  1777.       return 0;
  1778.     com = (struct Comment *) com->List.Next;
  1779.       }
  1780.  
  1781.       if(tagmode && ap->TagName && !Func(ap, tagmode))
  1782.     return 0;
  1783.       if(tagmode != TAGMODE_TAGS && ap->FuncName && !Func(ap, 0))
  1784.     return 0;
  1785.     }
  1786.   }
  1787.   while(com)
  1788.   {
  1789.     if(!DoOutput(comment, com->Data))
  1790.       return 0;
  1791.     com = (struct Comment *) com->List.Next;
  1792.   }
  1793.   return 1;
  1794. }
  1795.  
  1796. /* ------------------------------------------------------------------ */
  1797.  
  1798. /* return non zero, when ok, return 0xFFFFFFFF when STRPTR and not flags */
  1799. ULONG CopyCPPType(STRPTR buffer, STRPTR a, ULONG flag, STRPTR func,
  1800. struct AmiArgs *args)
  1801. {
  1802. /* when flag, then STRPTR is unsigned char * mode, else signed char * */
  1803.   ULONG ret = 1;
  1804.   ULONG k = 0;
  1805.   struct CPP_NameType nt;
  1806.  
  1807.   while((a = GetClibType(a)))
  1808.   {
  1809.     SDI_memset(&nt, 0, sizeof(struct CPP_NameType));
  1810.     GetCPPType(&nt, a);
  1811.  
  1812.     if(!flag && (nt.Flags & CPP_FLAG_STRPTR))
  1813.       ret = 0xFFFFFFFF;
  1814.  
  1815.     if(!nt.StructureName && !nt.Type)
  1816.     {
  1817.       APTR str;
  1818.       ULONG l = GetClibLength(a);
  1819.  
  1820.       if((str = AllocMem(l+1, MEMF_ANY|MEMF_CLEAR)))
  1821.     CopyMem(a, str, l);
  1822.  
  1823.       DoError(ERR_UNKNOWN_VARIABLE_TYPE, 0, str ? str : "?", func);
  1824.  
  1825.       if(str)
  1826.     FreeMem(str, l);
  1827.  
  1828.       return 0;
  1829.     }
  1830.     if((Flags & FLAG_LOCALREG) && (nt.Type != CPP_TYPE_VARARGS))
  1831.     {
  1832.       *(buffer++) = 'r';
  1833.       *(buffer++) = args[k].ArgReg + (args[k].ArgReg < 10 ? '0' : 'A'-10);
  1834.     }
  1835.     while(nt.PointerDepth--)
  1836.       *(buffer++) = 'P';
  1837.     if(nt.Flags & CPP_FLAG_CONST)
  1838.       *(buffer++) = 'C';
  1839.     if((nt.Flags & CPP_FLAG_UNSIGNED) || (flag && (nt.Flags & CPP_FLAG_STRPTR)))
  1840.       *(buffer++) = 'U';
  1841.     if(nt.Type)
  1842.       *(buffer++) = nt.Type;
  1843.     else
  1844.     {
  1845.       ULONG i;
  1846.       sprintf(buffer, "%02ld", nt.StructureLength); buffer += 2;
  1847.       for(i = 0; i < nt.StructureLength; ++i)
  1848.     *(buffer++) = nt.StructureName[i];
  1849.     }
  1850.     ++k;
  1851.   }
  1852.  
  1853.   *(buffer) = 0;
  1854.   return ret;
  1855. }
  1856.  
  1857. void GetCPPType(struct CPP_NameType *data, STRPTR start)
  1858. {
  1859.   ULONG a = 0;
  1860.   STRPTR u;
  1861.  
  1862.   while(a < 100)
  1863.   {
  1864.     start = SkipBlanks(start);
  1865.     if(!strncmp("...",start,3))
  1866.     {
  1867.       data->Type = CPP_TYPE_VARARGS; return;
  1868.     }
  1869.     if(!strncmp("const",start, 5))
  1870.     {
  1871.       data->Flags |= CPP_FLAG_CONST; start += 6;
  1872.     }
  1873.     else if(!strncmp("signed", start,6))
  1874.       start += 7;
  1875.     else if(!strncmp("unsigned",start,8))
  1876.     {
  1877.       data->Flags |= CPP_FLAG_UNSIGNED; start += 9;
  1878.     }
  1879.     else if(!strncmp("struct",start,6))
  1880.     {
  1881.       data->StructureName = SkipBlanks(start+6);
  1882.       start = SkipName(data->StructureName);
  1883.       data->StructureLength = start-data->StructureName;
  1884.       a = 100;
  1885.     }
  1886.     else if(!a)
  1887.     {
  1888.       ULONG i;
  1889.  
  1890.       for(i = 0; CPP_Field[i].Text; ++i)
  1891.       {
  1892.     if(!strncmp(start, CPP_Field[i].Text, CPP_Field[i].Length))
  1893.     {
  1894.       start += CPP_Field[i].Length + 1;
  1895.       data->Type = CPP_Field[i].Type;
  1896.       data->Flags |= (CPP_Field[i].Flags & ~CPP_FLAG_POINTER);
  1897.       if(data->Flags & CPP_FLAG_POINTER)
  1898.         ++data->PointerDepth;
  1899.       break;
  1900.     }
  1901.       }
  1902.       a = 2;
  1903.     }
  1904.     else
  1905.       a = 100;
  1906.   }
  1907.  
  1908.   do
  1909.   {
  1910.     u = SkipBlanks(start);
  1911.     if(*u == '*')
  1912.     {
  1913.       start = u+1; ++data->PointerDepth;
  1914.     }
  1915.   } while(*u == '*');
  1916. }
  1917.  
  1918. STRPTR FindClibFunc(STRPTR func) /* finds the needed function */
  1919. {
  1920.   ULONG len = strlen(func);
  1921.   STRPTR string, linestart, strend = clibbuf + clibsize;
  1922.   ULONG commentmode = 0;
  1923.  
  1924. #ifdef DEBUG_OLD
  1925.   VPrintf("FindClibFunc: %s\n", &func);
  1926. #endif
  1927.  
  1928.   if(!(linestart = string = clibbuf))
  1929.     return 0;
  1930.  
  1931.   do
  1932.   {
  1933.     while(*string && (commentmode || *string != '('/*)*/))
  1934.     {
  1935.       if(*(string++) == '/')
  1936.       {
  1937.     if(*string == '*')        /* start of comment */
  1938.       commentmode = 1;
  1939.     else if(*(string-2) == '*')    /* end of comment */
  1940.       commentmode = 0;
  1941.     else if(*string == '/')     /* skip line comments */
  1942.     {
  1943.       while(*string)
  1944.         ++string;
  1945.     }
  1946.       }
  1947.     }
  1948.     
  1949.     if(*string == '(' /*)*/)
  1950.     {
  1951.       while(*(--string) == ' ' || *string == '\t')
  1952.     ;
  1953.       if(!strncmp(func, string-len+1, len) && (*(string-len) == ' ' ||
  1954.       *(string-len) == '\t' || !*(string-len)))
  1955.     return linestart;
  1956.     }
  1957.     while(string < strend && *string)
  1958.       ++string;
  1959.     if(!*string)
  1960.       linestart = ++string;
  1961.   } while(string < strend);
  1962.   
  1963.   return 0;
  1964. }
  1965.  
  1966. ULONG GetClibLength(STRPTR start) /* returns length of the type */
  1967. {
  1968.   STRPTR old = start, u;
  1969.   ULONG a = 1;
  1970.  
  1971. #ifdef DEBUG_OLD
  1972.   VPrintf("GetClibLength:\n", 0);
  1973. #endif
  1974.  
  1975.   while(a)
  1976.   {
  1977.     start = SkipBlanks(start); a = 0;
  1978.     if(!strncmp("const",start, 5))
  1979.     {
  1980.       ++a; start += 6;
  1981.     }
  1982.     if(!strncmp("struct",start,6) || !strncmp("signed", start,6))
  1983.     {
  1984.       ++a; start += 7;
  1985.     }
  1986.     if(!strncmp("unsigned",start,8))
  1987.     {
  1988.       ++a; start += 9;
  1989.     }
  1990.   }
  1991.  
  1992.   while(*start && *start != ' ' && *start != '\t' && *start != '*')
  1993.    ++start;
  1994.  
  1995.   do
  1996.   {
  1997.     u = SkipBlanks(start);
  1998.     if(*u == '*')
  1999.       start = u+1;
  2000.   } while(*u == '*');
  2001.  
  2002.   return (ULONG) (start-old);
  2003. }
  2004.  
  2005. ULONG OutClibType(STRPTR start)
  2006. {
  2007.   UBYTE string[11];
  2008.   ULONG length = GetClibLength(start), i;
  2009.  
  2010. #ifdef DEBUG_OLD
  2011.   VPrintf("OutClibType:\n", 0);
  2012. #endif
  2013.  
  2014.   while(length)
  2015.   {
  2016.     if(length > 10)
  2017.       i = 10;
  2018.     else
  2019.       i = length;
  2020.  
  2021.     CopyMem(start, string, i);
  2022.     string[i] = '\0'; length -= i; start += i;
  2023.     if(!DoOutput(string))
  2024.       return 0;
  2025.   }
  2026.   return 1;
  2027. }
  2028.  
  2029. STRPTR GetClibType(STRPTR start) /* searches for next type definition */
  2030. {
  2031.   if(start == (STRPTR) deftype)
  2032.     return start;
  2033. #ifdef DEBUG_OLD
  2034.   VPrintf("GetClibType:\n", 0);
  2035. #endif
  2036.   while(*start && *start != '(' && *start != ',' && *start != ')')
  2037.     ++start;
  2038.   if(!*start || *start == /*(*/')')
  2039.     return 0;
  2040.   return SkipBlanks(++start);
  2041. }
  2042.  
  2043. /* ------------------------------------------------------------------ */
  2044.  
  2045. ULONG CallPrag(ULONG tagmode, STRPTR type,
  2046. ULONG (*Func) (struct AmiPragma *, ULONG))
  2047. {
  2048.   if(type)
  2049.     if((*type && !DoOutput("#if%s\n", type)) ||
  2050.     !(CallFunc(tagmode, tagmode ? 0 : "/%s */\n", Func)) ||
  2051.     (*type && !DoOutput("#endif\n")) || CTRL_C)
  2052.       return 0;
  2053.   return 1;
  2054. }
  2055.  
  2056. ULONG CreatePragmaFile(void)
  2057. {
  2058.   switch(MODE)
  2059.   {
  2060.   case 1: DoOutput("#ifndef _INCLUDE_PRAGMA_%s_LIB_H\n#define _INCLUDE_PRAGMA_%s_LIB_H\n",
  2061.     ShortBaseNameUpper, ShortBaseNameUpper); break;
  2062.   case 2: DoOutput("#ifndef PRAGMAS_%s_LIB_H\n#define PRAGMAS_%s_LIB_H\n",
  2063.     ShortBaseNameUpper, ShortBaseNameUpper); break;
  2064.   case 3: DoOutput("#ifndef PRAGMAS_%s_PRAGMAS_H\n#define PRAGMAS_%s_PRAGMAS_H\n",
  2065.     ShortBaseNameUpper, ShortBaseNameUpper); break;
  2066.   case 4: break;
  2067.   default: return 0;
  2068.   }
  2069.  
  2070.   if(HEADER)
  2071.   {
  2072.     DoOutput("\n");
  2073.     DoOutputDirect(HEADER, headersize);
  2074.   }
  2075.  
  2076.   if(MODE != 4 && !DoOutput("\n#ifndef CLIB_%s_PROTOS_H\n#include "
  2077.   "<clib/%s_protos.h>\n#endif\n\n", ShortBaseNameUpper, ShortBaseName))
  2078.     return 0;
  2079.  
  2080.   if((Flags & FLAG_EXTERNC) &&
  2081.   !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
  2082.     return 0;
  2083.  
  2084.   if(
  2085.   !CallPrag(TAGMODE_NORMAL, AMICALL, FuncAMICALL) ||
  2086.   !CallPrag(TAGMODE_NORMAL, LIBCALL, FuncLIBCALL))
  2087.     return 0;
  2088.  
  2089.   if(tagfuncs)
  2090.   {
  2091.     if(
  2092.     !CallPrag(TAGMODE_TAGS, AMITAGS, FuncAMICALL) ||
  2093.     !CallPrag(TAGMODE_TAGS, LIBTAGS, FuncLIBCALL) ||
  2094.     !CallPrag(TAGMODE_TAGS, CSTUBS,  FuncCSTUBS))
  2095.       return 0;
  2096.   }
  2097.  
  2098.   if((Flags & FLAG_EXTERNC) &&
  2099.   !DoOutput("\n#ifdef __cplusplus\n}\n#endif\n"))
  2100.     return 0;
  2101.  
  2102.   switch(MODE)
  2103.   {
  2104.   case 1: DoOutput("\n#endif\t/*  _INCLUDE_PRAGMA_%s_LIB_H  */",
  2105.     ShortBaseNameUpper); break;
  2106.   case 2: DoOutput("\n#endif\t/*  PRAGMAS_%s_LIB_H  */",
  2107.     ShortBaseNameUpper); break;
  2108.   case 3: DoOutput("\n#endif\t/*  PRAGMAS_%s_PRAGMA_H  */",
  2109.     ShortBaseNameUpper); break;
  2110.   case 4: break;
  2111.   default: return 0;
  2112.   }
  2113.   return Output_Error;
  2114. }
  2115.  
  2116. ULONG CreateLVOFile(ULONG mode)
  2117. {
  2118.   STRPTR data = "_LVO_I";
  2119.  
  2120.   if(mode == 2 || mode == 4)
  2121.     data = "_LIB_I";
  2122.  
  2123.   if(!DoOutput("\t\tIFND LIBRARIES_%s%s\nLIBRARIES_%s%s\tSET\t1\n\n",
  2124.   ShortBaseNameUpper, data, ShortBaseNameUpper, data) ||
  2125.   (HEADER && (!DoOutput("\n") || !DoOutputDirect(HEADER, headersize))) ||
  2126.   (mode <= 2 && !CallFunc(TAGMODE_NORMAL, 0, FuncLVOXDEF)) ||
  2127.   !CallFunc(TAGMODE_NORMAL, "\n%s", FuncLVO) ||
  2128.   !DoOutput("\n\n\t\tENDC") || CTRL_C)
  2129.     return 0;
  2130.  
  2131.   return 1;
  2132. }
  2133.  
  2134. ULONG CreateAsmStubs(ULONG mode)
  2135. {
  2136.   /* 1 = Text, 2 = Code */
  2137.   switch(mode)
  2138.   {
  2139.   case 1:
  2140.     if((HEADER && (!DoOutput("\n") || !DoOutputDirect(HEADER, headersize))) ||
  2141.     !DoOutput("\tSECTION\t \"%s_STUBS\",CODE\n\tXREF\t_%s\n",
  2142.     ShortBaseNameUpper, BaseName) ||
  2143.     !CallFunc(MODE, 0, FuncAsmText))
  2144.       return 0;
  2145.     break;
  2146.   case 2:
  2147.     if(!CallFunc(MODE, 0, FuncAsmCode))
  2148.       return 0;
  2149.     break;
  2150.   }
  2151.  
  2152.   if(CTRL_C)
  2153.     return 0;
  2154.   return 1;
  2155. }
  2156.  
  2157. ULONG CreateProtoFile(ULONG Type)
  2158. {
  2159.   STRPTR str1 = "pragma", str2 = "lib", str3 = "Library";
  2160.   ULONG i;
  2161.  
  2162.   for(i = 0; Proto_LibTypes[i].BaseName; ++i)
  2163.   {
  2164.     if(!(strcmp(Proto_LibTypes[i].BaseName, BaseName)))
  2165.     {
  2166.       str3 = Proto_LibTypes[i].StructureName; break;
  2167.     }
  2168.   }
  2169.  
  2170.   DoOutput("#ifndef _PROTO_%s_H\n#define _PROTO_%s_H\n", ShortBaseNameUpper,
  2171.   ShortBaseNameUpper);
  2172.  
  2173.   if(HEADER)
  2174.   {
  2175.     DoOutput("\n");
  2176.     DoOutputDirect(HEADER, headersize);
  2177.   }
  2178.  
  2179.   switch(Type)
  2180.   {
  2181.     case 4: str1 = "pragmas"; /* no break; */
  2182.     case 2: str2 = "pragmas"; break;
  2183.     case 3: str1 = "pragmas"; break;
  2184.     case 5: str1 = "local"; str2 = "loc"; break;
  2185.   }
  2186.  
  2187.   DoOutput("\n");
  2188.   if(Type == 6)
  2189.     DoOutput("#ifndef __NOLIBBASE__\n  ");
  2190.   DoOutput("extern struct %s *%s;\n", str3, BaseName);
  2191.   if(Type == 6)
  2192.     DoOutput("#endif\n");
  2193.   DoOutput("\n#include <exec/types.h>\n");
  2194.   if(Type != 5)
  2195.     DoOutput("#include <clib/%s_protos.h>\n", ShortBaseName);
  2196.   if(Type == 6)
  2197.     DoOutput("\n#ifdef " TEXT_GNUC "\n  #include <inline/%s.h>\n#else\n  ",
  2198.     ShortBaseName);
  2199.   DoOutput("#include <%s/%s_%s.h>\n", str1, ShortBaseName, str2);
  2200.   if(Type == 6)
  2201.     DoOutput("#endif\n");
  2202.  
  2203.   return DoOutput("\n#endif\t/*  _PROTO_%s_H  */\n", ShortBaseNameUpper);
  2204. }
  2205.  
  2206. ULONG CreateLocalData(void)
  2207. {
  2208.   UBYTE a[40];
  2209.  
  2210.   DoOutput("#ifndef _INCLUDE_PROTO_%s_LOC_H\n#define _INCLUDE_PROTO_%s_LOC_H\n\n",
  2211.   ShortBaseNameUpper, ShortBaseNameUpper);
  2212.   
  2213.   if(HEADER)
  2214.   {
  2215.     DoOutput("\n");
  2216.     DoOutputDirect(HEADER, headersize);
  2217.   }
  2218.  
  2219.   { /* copies the include lines */
  2220.     STRPTR str = clibbuf, strend = clibbuf + clibsize;
  2221.     ULONG i = 0;
  2222.  
  2223.     /* works too, when no clibbuf, because then following is everytime false */
  2224.     while(str < strend)
  2225.     {
  2226.       if(!strncmp(str, "#include", 8))
  2227.       {
  2228.     DoOutput("%s\n",str); ++i;
  2229.       }
  2230.       while(*(str++))
  2231.     ;
  2232.     }
  2233.     DoOutput(i ? "\n" : "#include <exec/types.h>\n\n");
  2234.   }
  2235.  
  2236.   if((Flags & FLAG_EXTERNC) &&
  2237.   !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
  2238.     return 0;
  2239.  
  2240.   if(!CallFunc(MODE, 0, FuncLocText))
  2241.     return 0;
  2242.  
  2243.   if((Flags & FLAG_EXTERNC) &&
  2244.   !DoOutput("#ifdef __cplusplus\n}\n#endif\n\n"))
  2245.     return 0;
  2246.  
  2247.   DoOutput("#endif\t/*  _INCLUDE_PROTO_%s_LOC_H  */", ShortBaseNameUpper);
  2248.   Out(out.size); /* clears buffer */
  2249.  
  2250.   sprintf(a, "%s_loc.lib", ShortBaseName);
  2251.   Close(out.file);
  2252.   if(!(out.file = Open(a, MODE_NEWFILE)))
  2253.     return 0;
  2254.  
  2255.   return CallFunc(MODE, 0, FuncLocCode);
  2256. }
  2257.  
  2258. /* ------------------------------------------------------------------ */
  2259.  
  2260. ULONG GetName(struct NameList *t, struct ShortListRoot *p, ULONG args)
  2261. {
  2262.   struct NameList *p2 = (struct NameList *) p->First;
  2263.   struct AmiPragma ap;
  2264.   ap.FuncName = t->NormName;
  2265.   ap.NumArgs = 1;
  2266.   ap.Args[0].ArgName = (args ? "args" : "tags");
  2267.   if(!MakeTagFunction(&ap))
  2268.     return 0;
  2269.  
  2270.   while(p2 && strcmp(p2->PragName, ap.TagName))
  2271.    p2 = (struct NameList *) p2->List.Next;
  2272.  
  2273.   if(!p2)
  2274.     return 0;
  2275.  
  2276.   t->Type = (args ? NTP_ARGS : NTP_TAGS);
  2277.   t->PragName = ap.TagName;
  2278.   RemoveItem(p, (struct ShortList *) p2);
  2279.  
  2280. #ifdef DEBUG_OLD
  2281.   VPrintf("GetName: name matches - %s _ %s\n", &t->NormName);
  2282. #endif
  2283.  
  2284.   return 1;
  2285. }
  2286.  
  2287. void OptimizeFDData(struct PragData *pd)
  2288. {
  2289. #ifdef DEBUG_OLD
  2290.   PutStr("OptimizeFDData\n");
  2291. #endif
  2292.  
  2293.   while(pd && !CTRL_C)
  2294.   {
  2295.     if(pd->NumNames > 1)
  2296.     {
  2297.       struct ShortListRoot n = {0,0,0}, p = {0,0,0};
  2298.       struct NameList *t;
  2299.       while(pd->Name.First)    /* sorts in AmiCall and TagCall */
  2300.       {
  2301.     t = (struct NameList *) pd->Name.First;
  2302.  
  2303.     RemoveItem(&pd->Name, (struct ShortList *) t);
  2304.     AddItem(t->PragName ? &p : &n, (struct ShortList *) t);
  2305.       }
  2306.  
  2307.       if(p.First)
  2308.       {
  2309.     t = (struct NameList *) n.First;
  2310.     while(p.First && t)
  2311.     {
  2312.       if(!GetName(t, &p, 0))
  2313.       {
  2314.         GetName(t, &p, 1);
  2315.       }
  2316.       if(t->PragName)
  2317.       {
  2318.         struct NameList *t2 = (struct NameList *) t->List.Next;
  2319.         RemoveItem(&n, (struct ShortList *)t);
  2320.         AddItem(&pd->Name, (struct ShortList *) t);
  2321.         t = t2;
  2322.       }
  2323.       else
  2324.         t = (struct NameList *) t->List.Next;
  2325.     }
  2326.     while(p.First)
  2327.     {
  2328.       if(n.First)
  2329.       {
  2330.         t = (struct NameList *) n.First;
  2331.         t->PragName = ((struct NameList *)(p.First))->PragName;
  2332.         RemoveItem(&n, (struct ShortList *) t);
  2333. #ifdef DEBUG_OLD
  2334.         VPrintf("OptimizeFDData: names together - %s _ %s\n", &t->NormName);
  2335. #endif
  2336.         t->Type = NTP_UNKNOWN;
  2337.       }
  2338.       else
  2339.       {
  2340.         ULONG i;
  2341.  
  2342.         t = (struct NameList *) p.First;
  2343.         i = strlen(t->PragName);
  2344.         t->NormName = strndup(t->PragName, i+1);
  2345.         t->NormName[i++] = 'A';
  2346.         t->NormName[i] = 0;
  2347.         t->Type = NTP_TAGS;
  2348. #ifdef DEBUG_OLD
  2349.         VPrintf("OptimizeFDData: NormName created - %s _ %s\n", &t->NormName);
  2350. #endif
  2351.       }
  2352.  
  2353.       AddItem(&pd->Name, (struct ShortList *) t);
  2354.       RemoveItem(&p, p.First);
  2355.     }
  2356.       }
  2357.  
  2358.       AddItem(&pd->Name, n.First); /* add left NormNames */
  2359.     }
  2360.     pd = (struct PragData *) pd->List.Next;
  2361.   }
  2362. }
  2363.  
  2364. ULONG MakeFD(struct PragList *pl)
  2365. {
  2366.   struct PragData *pd = (struct PragData *) pl->Data.First;
  2367.   ULONG bias;
  2368.  
  2369. #ifdef DEBUG_OLD
  2370.   PutStr("MakeFD\n");
  2371. #endif
  2372.   bias = pd->Bias;
  2373.  
  2374.   OptimizeFDData(pd);
  2375. #ifdef DEBUG_OLD
  2376.   PutStr("MakeFD: after Optimizing\n");
  2377. #endif
  2378.   DoOutput("##base _%s\n##bias %ld\n##public\n", pl->Basename, bias);
  2379.  
  2380.   while(pd && !CTRL_C && Output_Error)
  2381.   {
  2382.     struct NameList *n = (struct NameList *) pd->Name.First;
  2383.  
  2384.     if(bias != pd->Bias)
  2385.       DoOutput("##bias %ld\n", (bias = pd->Bias));
  2386.  
  2387.     while(n)
  2388.     {
  2389.       STRPTR lastpar = "last";
  2390.       ULONG i;
  2391.  
  2392.       if(n->Type == NTP_TAGS)
  2393.     lastpar = "tags";
  2394.       else if(n->Type == NTP_ARGS)
  2395.     lastpar = "args";
  2396.  
  2397.       DoOutput("%s("/*)*/,n->NormName);
  2398.       if(!pd->NumArgs)
  2399.     DoOutput(/*(*/")()\n");
  2400.       else
  2401.       {
  2402.     for(i = 0; i < pd->NumArgs-1; ++i)
  2403.       DoOutput("par%ld,",i+1);
  2404.     DoOutput("%s)(", lastpar);
  2405.     for(i = 0; i < pd->NumArgs-1; ++i)
  2406.       DoOutput("%s,", &RegNames[(pd->ArgReg[i])<<2]);
  2407.     DoOutput("%s)\n", &RegNames[(pd->ArgReg[i])<<2]);
  2408.  
  2409.     if(n->Type == NTP_UNKNOWN)
  2410.     {
  2411.       ULONG i;
  2412.       for(i = 0; n->NormName[i] == n->PragName[i]; ++i)
  2413.         ;
  2414.       DoOutput("*tagcall");
  2415.       if(n->NormName[i])
  2416.         DoOutput("-%s", n->NormName+i);
  2417.       if(n->PragName[i])
  2418.         DoOutput("+%s", n->PragName+i);
  2419.  
  2420.       DoOutput("\n");
  2421.     }
  2422.       }
  2423.       if((n = (struct NameList *) n->List.Next))
  2424.     DoOutput("##bias %ld\n", pd->Bias);
  2425.     }
  2426.  
  2427.     pd = (struct PragData *)pd->List.Next; bias += 6;
  2428.   }
  2429.  
  2430.   if(CTRL_C)
  2431.     return 0;
  2432.  
  2433.   DoOutput("##end\n");
  2434.  
  2435.   return Output_Error;
  2436. }
  2437.  
  2438. ULONG AddFDData(struct ShortListRoot *pls, struct FDData *fd)
  2439. {
  2440.   struct NameList *t;
  2441.   struct PragList *pl = (struct PragList *) pls->First;
  2442.   struct PragData *pd;
  2443.  
  2444.   while(pl && strcmp(pl->Basename, fd->Basename))
  2445.     pl = (struct PragList *) pl->List.Next;
  2446.  
  2447.   if(!pl)
  2448.   {
  2449. #ifdef DEBUG_OLD
  2450.   VPrintf("AddFDData: New PragList - %s\n", &fd->Basename);
  2451. #endif
  2452.     if(!(pl = (struct PragList *) NewItem(pls)))
  2453.       return 100;
  2454.     pl->Basename = fd->Basename;
  2455.     pl->Data.Size = sizeof(struct PragData);
  2456.     AddItem(pls, (struct ShortList *) pl);
  2457.   }
  2458.  
  2459.   if((pd = (struct PragData *) pl->Data.First))
  2460.   {
  2461.     while(pd->List.Next && ((struct PragData *) pd->List.Next)->Bias
  2462.     <= fd->Bias)
  2463.       pd = (struct PragData *) pd->List.Next;
  2464.   }
  2465.  
  2466.   if(!pd || pd->Bias != fd->Bias)
  2467.   {
  2468.     struct PragData *pd2;
  2469. #ifdef DEBUG_OLD
  2470.     {
  2471.       ULONG args[2];
  2472.       args[0] = fd->Bias;
  2473.       args[1] = fd->NumArgs;
  2474.       VPrintf("AddFDData: New PragData - %ld, %ld\n", &args);
  2475.     }
  2476. #endif
  2477.     if(!(pd2 = (struct PragData *) NewItem(&pl->Data)))
  2478.       return 100;
  2479.     pd2->Bias = fd->Bias;
  2480.     CopyMem(fd->ArgReg, pd2->ArgReg, 14);
  2481.     pd2->NumArgs = fd->NumArgs;
  2482.     pd2->Name.Size = sizeof(struct NameList);
  2483.     if(!pd)
  2484.       AddItem(&pl->Data, (struct ShortList *) pd2);
  2485.     else if(pd->Bias > fd->Bias) /* Insert at start */
  2486.     {
  2487.       pd2->List.Next = pl->Data.First;
  2488.       pl->Data.First = (struct ShortList *) pd2;
  2489.     }
  2490.     else /* Insert the entry */
  2491.     {
  2492.       pd2->List.Next = pd->List.Next;
  2493.       pd->List.Next = (struct ShortList *) pd2;
  2494.     }
  2495.     pd = pd2;
  2496.   }
  2497.   else
  2498.   {
  2499.     ULONG i = fd->NumArgs;
  2500.     if(fd->NumArgs != pd->NumArgs)
  2501.       return ERR_DIFFERENT_TO_PREVIOUS;
  2502.  
  2503.     while(i--)
  2504.     {
  2505.       if(fd->ArgReg[i] != pd->ArgReg[i])
  2506.     return ERR_DIFFERENT_TO_PREVIOUS;
  2507.     }
  2508.   }
  2509.  
  2510.   t = (struct NameList *) pd->Name.First;    /* skips same names */
  2511.   while(t && strcmp(fd->Name, fd->Mode ? t->PragName : t->NormName))
  2512.     t = (struct NameList *) t->List.Next;
  2513.  
  2514.   if(t)
  2515.     return 0;
  2516.  
  2517.   if(!(t = (struct NameList *) NewItem(&pd->Name)))
  2518.     return 100;
  2519.   if(fd->Mode)
  2520.     t->PragName = fd->Name;
  2521.   else
  2522.     t->NormName = fd->Name;
  2523.   AddItem(&pd->Name, (struct ShortList *) t);
  2524.   ++(pd->NumNames);
  2525. #ifdef DEBUG_OLD
  2526.   VPrintf("AddFDData: New NameList - %s\n", &fd->Name);
  2527. #endif
  2528.   return 0;
  2529. }
  2530.  
  2531. UBYTE GetHexValue(UBYTE data)
  2532. {
  2533.   if(data >= 'a')
  2534.     return (UBYTE) (data - 'a' + 10);
  2535.   else if(data >= 'A')
  2536.     return (UBYTE) (data - 'A' + 10);
  2537.   else
  2538.     return (UBYTE) (data - '0');
  2539. }
  2540.  
  2541. ULONG GetLibData(struct FDData *fd)
  2542. {
  2543.   ULONG i;
  2544.   fd->Name = SkipBlanks(in.pos);
  2545.   in.pos = SkipName(fd->Name); *(in.pos++) = 0;
  2546.   in.pos = SkipBlanks(in.pos);
  2547.   fd->Bias = strtoul(in.pos, 0, 16);
  2548.   while(*in.pos)
  2549.     ++in.pos;
  2550.   if((fd->NumArgs = GetHexValue(*(--in.pos))) > 14)
  2551.     return ERR_TO_MUCH_ARGUMENTS;
  2552.   --in.pos; /* skips return register */
  2553.   for(i = 0; i < fd->NumArgs; ++i)
  2554.   {
  2555.     if((fd->ArgReg[i] = GetHexValue(*(--in.pos))) > 14)
  2556.       return ERR_EXPECTED_REGISTER_NAME;
  2557.   }
  2558.   return 0;
  2559. }
  2560.  
  2561. ULONG GetAmiData(struct FDData *fd)
  2562. {
  2563.   STRPTR endptr;
  2564.   in.pos = SkipBlanks(in.pos);
  2565.   if(*in.pos != '('/*)*/)
  2566.     return ERR_EXPECTED_OPEN_BRACKET;
  2567.   fd->Basename = ++in.pos;
  2568.   in.pos = SkipBlanks(endptr = SkipName(in.pos));
  2569.   if(*in.pos != ',')
  2570.     return ERR_EXPECTED_COMMA;
  2571.   *endptr = 0;
  2572.   in.pos = SkipBlanks(++in.pos);
  2573.   if(!strncmp(in.pos, "0x", 2))
  2574.     fd->Bias = strtoul(in.pos+2, 0, 16);
  2575.   else
  2576.     fd->Bias = strtoul(in.pos, 0, 10);
  2577.  
  2578.   in.pos = SkipBlanks(SkipName(in.pos));
  2579.   if(*in.pos != ',')
  2580.     return ERR_EXPECTED_COMMA;
  2581.   fd->Name = in.pos = SkipBlanks(++in.pos);
  2582.   in.pos = SkipBlanks(endptr = SkipName(in.pos));
  2583.   if(*in.pos != '('/*)*/)
  2584.     return ERR_EXPECTED_OPEN_BRACKET;
  2585.   *endptr = 0;
  2586.   in.pos = SkipBlanks(++in.pos);
  2587.   if(*in.pos == /*(*/')')
  2588.     return 0;
  2589.   --in.pos;
  2590.   while(*in.pos != /*(*/')')
  2591.   {
  2592.     ULONG i;
  2593.     in.pos = SkipBlanks(in.pos+1);
  2594.     for(i = 0; i < 16; i++)
  2595.       if(!strnicmp(&RegNames[i<<2], in.pos, 2))
  2596.     break;
  2597.     if(i == 16)
  2598.       return ERR_EXPECTED_REGISTER_NAME;
  2599.     if(i > 14)
  2600.       return ERR_ILLEGAL_REGISTER;
  2601.  
  2602.     if(fd->NumArgs > 14)
  2603.       return ERR_TO_MUCH_ARGUMENTS;
  2604.  
  2605.     fd->ArgReg[fd->NumArgs] = i; ++fd->NumArgs;
  2606.  
  2607.     in.pos = SkipBlanks(in.pos+2);
  2608.  
  2609.     if(*in.pos != ',' && *in.pos != ')')
  2610.       return ERR_EXPECTED_CLOSE_BRACKET;
  2611.   }
  2612.   in.pos = SkipBlanks(in.pos+1);
  2613.   if(*in.pos != ')')
  2614.     return ERR_EXPECTED_CLOSE_BRACKET;
  2615.   return 0;
  2616. }
  2617.  
  2618. ULONG CreateFDFile(STRPTR file, STRPTR to)
  2619. {
  2620.   struct ShortListRoot pl = {0, 0, sizeof(struct PragList)};
  2621.   ULONG linenum, err = 0, skip;
  2622.  
  2623.   for(linenum = 1; !CTRL_C && in.pos < in.buf + in.size; ++linenum)
  2624.   {
  2625.     in.pos = SkipBlanks(in.pos);
  2626.     if(!strncmp("#pragma", in.pos, 7))
  2627.     {
  2628.       struct FDData fd;
  2629.       
  2630.       skip = 0;
  2631.       memset(&fd, 0, sizeof(struct FDData));
  2632.  
  2633.       in.pos = SkipBlanks(in.pos+7);
  2634.       if(!strncmp("tagcall", in.pos, 7))
  2635.       {
  2636.     fd.Mode = 1;
  2637.     in.pos = SkipBlanks(in.pos+7);
  2638.     if(*in.pos == '(' /*)*/)    /* Storm method */
  2639.       err = GetAmiData(&fd);
  2640.     else                /* SAS method */
  2641.     {
  2642.       fd.Basename = in.pos;
  2643.       in.pos = SkipName(fd.Basename); *(in.pos++) = 0;
  2644.       err = GetLibData(&fd);
  2645.     }
  2646.       }
  2647.       else if(!strncmp("amicall", in.pos, 7))    /* Storm method */
  2648.       {
  2649.     in.pos += 7;
  2650.     err = GetAmiData(&fd);
  2651.       }
  2652.       else if(!strncmp("libcall", in.pos, 7))    /* SAS method */
  2653.       {
  2654.     fd.Basename = SkipBlanks(in.pos+7);
  2655.     in.pos = SkipName(fd.Basename); *(in.pos++) = 0;
  2656.     err = GetLibData(&fd);
  2657.       }
  2658.       else if(!strncmp("syscall", in.pos, 7))    /* SAS method */
  2659.       {
  2660.     fd.Basename = "SysBase";
  2661.     err = GetLibData(&fd);
  2662.       }
  2663.       else
  2664.     skip = 1;
  2665.  
  2666.       if(err)
  2667.     DoError(err, linenum);
  2668.       else if(skip)
  2669.     ;
  2670.       else if((err = AddFDData(&pl, &fd)))
  2671.       {
  2672.     if(err != 100)
  2673.       DoError(err, linenum);
  2674.     return 0;
  2675.       }
  2676.     }
  2677.     while(*(in.pos++))    /* jumps to first char of next line */
  2678.       ;
  2679.   }
  2680.  
  2681.   if(pl.First && !CTRL_C)
  2682.   {
  2683.     struct PragList *p = (struct PragList *) pl.First;
  2684.     if(!p->List.Next)
  2685.     {
  2686.       if(!to)
  2687.       {
  2688.     STRPTR text;
  2689.     ULONG i;
  2690.     
  2691.     if(ShortBaseName)
  2692.     {
  2693.       text = ShortBaseName; i = strlen(text);
  2694.     }
  2695.     else
  2696.     {
  2697.       text = p->Basename; i = strlen(text)-4;
  2698.     }
  2699.  
  2700.     to = strndup(text, i + 7);
  2701.     CopyMem("_lib.fd", to+i, 8);
  2702.       }
  2703.       if(!(out.file = Open(to, MODE_NEWFILE)) || !MakeFD(p))
  2704.     return 0;
  2705.     }
  2706.     else
  2707.     {
  2708.       while(p)
  2709.       {
  2710.     ULONG i;
  2711.     i = strlen(p->Basename) - 4;
  2712.     to = strndup(p->Basename, i+7);
  2713.     CopyMem("_lib.fd", to+i, 8);
  2714.     if(!(out.file = Open(to, MODE_NEWFILE)) || !MakeFD(p))
  2715.       return 0;
  2716.     Out(out.size); /* free buffer */
  2717.     Close(out.file);
  2718.     out.file = 0;
  2719.     p = (struct PragList *) p->List.Next;
  2720.       }
  2721.     }
  2722.   }
  2723.  
  2724.   if(CTRL_C)
  2725.     return 0;
  2726.   return 1;
  2727. }
  2728.  
  2729. STRPTR helptext =
  2730. "FDFILE:  the FD file which should be used\n"
  2731. "SPECIAL: 1 - Aztec compiler (xxx_lib.h,     MODE 2, AMICALL)\n"
  2732. "\t 2 - DICE compiler  (xxx_pragmas.h, MODE 3, LIBCALL)\n"
  2733. "\t 3 - SAS compiler   (xxx_pragmas.h, MODE 3, LIBCALL,LIBTAGS)\n"
  2734. "\t 4 - MAXON compiler (xxx_lib.h,     MODE 1, AMICALL)\n"
  2735. "\t 5 - STORM compiler (xxx_lib.h,     MODE 1, AMITAGS,AMICALL)\n"
  2736. "\t 6 - all compilers [default]\n"
  2737. "\t10 - stub-functions for C - assembler text\n"
  2738. "\t11 - stub-functions for C - link library\n"
  2739. "\t12 - defines and link library for local library base (register call)\n"
  2740. "\t13 - defines and link library for local library base (stack call)\n"
  2741. "\t14 - stub-functions for Pascal - assembler text\n"
  2742. "\t15 - stub-functions for Pascal - link library\n"
  2743. "\t20 - assembler lvo _lvo.i file\n"
  2744. "\t21 - assembler lvo _lib.i file\n"
  2745. "\t22 - assembler lvo _lvo.i file no XDEF\n"
  2746. "\t23 - assembler lvo _lib.i file no XDEF\n"
  2747. "\t30 - proto file with pragma/..._lib.h call\n"
  2748. "\t31 - proto file with pragma/..._pragmas.h call\n"
  2749. "\t32 - proto file with pragmas/..._lib.h call\n"
  2750. "\t33 - proto file with pragmas/..._pragmas.h call\n"
  2751. "\t34 - proto file with local/..._loc.h call\n"
  2752. "\t35 - proto file for all compilers\n"
  2753. "\t50 - FD file (source is a pragma file!)\n"
  2754. "TO:\t the destination directory (self creation of filename) or\n"
  2755. "\t the destination file\n"
  2756. "COMMENT: copy comments found in FD file\n"
  2757. "MODE:\t SPECIAL 1-6,AMICALL,LIBCALL,AMITAGS,LIBTAGS,CSTUBS:\n"
  2758. "\t 1 - _INCLUDE_PRAGMA_..._LIB_H definition method [default]\n"
  2759. "\t 2 - _PRAGMAS_..._LIB_H definition method\n"
  2760. "\t 3 - _PRAGMAS_..._PRAGMAS_H definition method\n"
  2761. "\t 4 - no definition\n"
  2762. "\t SPECIAL 10-13:\n"
  2763. "\t 0 - all functions, normal interface\n"
  2764. "\t 1 - only tag-functions, tagcall interface [default]\n"
  2765. "\t 2 - all functions, normal and tagcall interface\n"
  2766. "AMICALL: creates amicall pragmas\n"
  2767. "LIBCALL: creates libcall pragmas\n"
  2768. "AMITAGS: creates tagcall pragmas (amicall like method (StormC++))\n"
  2769. "LIBTAGS: creates tagcall pragmas (libcall like method (SAS C))\n"
  2770. "CSTUBS:  creates stub functions in C code\n"
  2771. "The last five need a string as argument. This string is used to set\n"
  2772. "a #if<given string> before the set method.\n"
  2773. "EXTERNC: add a #ifdef __cplusplus ... statement to pragma file\n"
  2774. "USESYSCALL: uses syscall pragma instead of libcall SysBase\n"
  2775. "CLIB:    name of the prototypes file in clib directory\n"
  2776. "PRIVATE: includes private declared functions\n"
  2777. "HEADER:  inserts given file into header of created file (\"\" is scan)\n"
  2778. "STORMFD: converts FD files of strange StormC++ format";
  2779.  
  2780. void main(void)
  2781. {
  2782.   ULONG mode = 0;
  2783.   ULONG spec = 0; /* for default setting I need a ULONG var to get a pointer */
  2784.   UBYTE filename[255];    /* needed for filename */
  2785.   struct
  2786.   {
  2787.     STRPTR FDFILE;
  2788.     ULONG* SPECIAL;
  2789.     STRPTR TO;
  2790.     ULONG  COMMENT;
  2791.     ULONG* MODE;
  2792.     STRPTR AMICALL;
  2793.     STRPTR LIBCALL;
  2794.     STRPTR AMITAGS;
  2795.     STRPTR LIBTAGS;
  2796.     STRPTR CSTUBS;
  2797.     ULONG  EXTERNC;
  2798.     ULONG  USESYSCALL;
  2799.     STRPTR CLIB;
  2800.     ULONG  PRIVATE;
  2801.     STRPTR HEADER;
  2802.     ULONG  STORMFD;
  2803.   } args = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  2804.  
  2805.   args.SPECIAL = &spec;
  2806.  
  2807. #ifdef __SASC    /* with __MAXON__ this is done automatic by my StartUp */
  2808.   TestOS;
  2809. #endif
  2810.  
  2811.   if(!(rda = (struct RDArgs *) AllocDosObject(DOS_RDARGS, 0)))
  2812.     End(RETURN_FAIL);
  2813.   rda->RDA_ExtHelp = helptext;
  2814.   if(!ReadArgs(PARAM, (LONG *) &args, rda))
  2815.     End(RETURN_FAIL);
  2816.  
  2817.   VPrintf("SourceFile: %s\n", &args.FDFILE);
  2818.  
  2819.   if(
  2820.   !(in.file = Open(args.FDFILE, MODE_OLDFILE)) ||
  2821.   !(IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 37)) ||
  2822.   !(fib = (struct FileInfoBlock *) AllocDosObject(DOS_FIB, 0)) ||
  2823.   !ExamineFH(in.file, fib) ||
  2824.   !(in.buf = in.pos = (STRPTR) AllocRemember(&remember, (in.size = fib->fib_Size)+1, MEMF_ANY)) ||
  2825.   Read(in.file, in.buf, in.size) != in.size ||
  2826.   !(out.buf = out.pos = (STRPTR) AllocRemember(&remember, out.size, MEMF_ANY)))
  2827.     End(RETURN_FAIL);
  2828.  
  2829.   {
  2830.     STRPTR ptr = FilePart(args.FDFILE);
  2831.     LONG len = strlen(ptr)-7;
  2832.     if(len >= 0 && !stricmp(ptr+len, "_lib.fd"))
  2833.     {
  2834.       ShortBaseName = ptr;
  2835.       ptr[len] = '\0';
  2836.     }
  2837.   }
  2838.  
  2839.   MakeLines(in.pos, in.size, 0);
  2840.  
  2841.   if(args.CLIB)
  2842.   {
  2843.     Close(in.file);
  2844.     if(!(in.file = Open(args.CLIB, MODE_OLDFILE)) ||
  2845.     !ExamineFH(in.file, fib) ||
  2846.     !(clibbuf = (STRPTR) AllocRemember(&remember, (clibsize = fib->fib_Size)+1, MEMF_ANY)) ||
  2847.     Read(in.file, clibbuf, clibsize) != clibsize)
  2848.       End(RETURN_FAIL);
  2849.     MakeLines(clibbuf, clibsize, 1);
  2850.   }
  2851.   Close(in.file); in.file = 0;
  2852.  
  2853.   if(args.TO)
  2854.   {
  2855.     if((lock = Lock(args.TO, SHARED_LOCK)) && Examine(lock, fib) &&
  2856.     fib->fib_DirEntryType > 0)
  2857.     {
  2858.       oldfh = CurrentDir(lock);
  2859.       args.TO = 0;
  2860.     }
  2861.     else if(lock)
  2862.     {
  2863.       UnLock(lock);
  2864.       lock = 0;
  2865.     }
  2866.   }
  2867.  
  2868.   if(*args.SPECIAL == 50)
  2869.   {
  2870.     STRPTR ptr = FilePart(args.FDFILE), ptr2;
  2871.  
  2872.     for(ptr2 = ptr; *ptr2 && *ptr2 != '_' && *ptr2 != '.'; ++ptr2)
  2873.       ;
  2874.     if(ptr2 != ptr)
  2875.     {
  2876.       ShortBaseName = ptr;
  2877.       *ptr2 = '\0';
  2878.     }
  2879.     if(!CreateFDFile(args.FDFILE, args.TO))
  2880.       End(RETURN_FAIL);
  2881.     End(RETURN_OK);
  2882.   }
  2883.  
  2884.   if(args.EXTERNC)        Flags ^= FLAG_EXTERNC;
  2885.   if(args.STORMFD)        Flags ^= FLAG_STORMFD;
  2886.   if(args.COMMENT)        Flags ^= FLAG_DOCOMMENT;
  2887.   if(args.PRIVATE)        Flags ^= FLAG_PRIVATE;
  2888.  
  2889.   if(!ScanFDFile())
  2890.     End(RETURN_FAIL);
  2891.  
  2892.   if(*args.SPECIAL < 10)
  2893.   {
  2894.     mode = MODUS_PRAGMA;
  2895.     sprintf(filename, "%s_lib.h", ShortBaseName);
  2896.  
  2897.     if(!args.LIBTAGS && !args.AMITAGS && !args.LIBCALL && !args.AMICALL &&
  2898.     !args.CSTUBS && !*args.SPECIAL)
  2899.       *args.SPECIAL = 6;
  2900.  
  2901.     switch(*args.SPECIAL)
  2902.     {
  2903.       case 0: break;
  2904.       case 1: MODE = 2; AMICALL = ""; break;
  2905.       case 2: sprintf(filename, "%s_pragmas.h", ShortBaseName);
  2906.           MODE = 3; LIBCALL = ""; break;
  2907.       case 3: sprintf(filename, "%s_pragmas.h", ShortBaseName);
  2908.           MODE = 3; LIBCALL = ""; LIBTAGS = "def " TEXT_SAS_60; break;
  2909.       case 4: MODE = 1; AMICALL = ""; break;
  2910.       case 5: MODE = 1; AMICALL = AMITAGS = ""; break;
  2911.       case 6: MODE = 1; AMICALL = " defined(" TEXT_AZTEC ") || defined("
  2912.     TEXT_MAXON ") || defined(" TEXT_STORM ")";
  2913.     LIBCALL = " defined(" TEXT_DICE ") || defined(" TEXT_SAS ")";
  2914.     LIBTAGS = "def " TEXT_SAS_60; AMITAGS ="def " TEXT_STORM; break;
  2915.       default: mode = MODUS_ERROR;
  2916.     }
  2917.  
  2918.     if(args.AMICALL)        AMICALL = args.AMICALL;
  2919.     if(args.LIBCALL)        LIBCALL = args.LIBCALL;
  2920.     if(args.AMITAGS)        AMITAGS = args.AMITAGS;
  2921.     if(args.LIBTAGS)        LIBTAGS = args.LIBTAGS;
  2922.     if(args.CSTUBS)        CSTUBS = args.CSTUBS;
  2923.     if(args.USESYSCALL)     Flags ^= FLAG_SYSCALL;
  2924.  
  2925.     if(args.MODE && *args.MODE > 0 && *args.MODE < 5)
  2926.       MODE = *args.MODE;
  2927.   }
  2928.   else if(*args.SPECIAL < 20)
  2929.   {
  2930.     switch(*args.SPECIAL)
  2931.     {
  2932.     case 10: mode = MODUS_STUBTEXT;
  2933.       sprintf(filename, "%s_stub.a", ShortBaseName); break;
  2934.     case 11: mode = MODUS_STUBCODE;
  2935.       sprintf(filename, "%s.lib", ShortBaseName); break;
  2936.     case 12: Flags |= FLAG_LOCALREG; /* no break ! */
  2937.     case 13: mode = MODUS_LOCALDATA;
  2938.       sprintf(filename, "%s_loc.h", ShortBaseName); args.TO = 0; break;
  2939.     case 14: mode = MODUS_STUBTEXT; MODE = 0; Flags ^= FLAG_PASCAL;
  2940.       sprintf(filename, "%s_stub.a", ShortBaseName); break;
  2941.     case 15: mode = MODUS_STUBCODE; MODE = 0; Flags ^= FLAG_PASCAL;
  2942.       sprintf(filename, "%s.lib", ShortBaseName); break;
  2943.     default: mode = MODUS_ERROR;
  2944.     }
  2945.     if(args.MODE && *args.MODE >= 0 && *args.MODE < 3)
  2946.       MODE = *args.MODE;
  2947.   }
  2948.   else if(*args.SPECIAL < 30)
  2949.   {
  2950.     switch(*args.SPECIAL)
  2951.     {
  2952.     case 20: case 22: mode = MODUS_LVO+*args.SPECIAL-20;
  2953.       sprintf(filename, "%s_lvo.i", ShortBaseName); break;
  2954.     case 21: case 23: mode = MODUS_LVO+*args.SPECIAL-20;
  2955.       sprintf(filename, "%s_lib.i", ShortBaseName); break;
  2956.     default: mode = MODUS_ERROR;
  2957.     }
  2958.   }
  2959.   else if(*args.SPECIAL < 40)
  2960.   {
  2961.     if(*args.SPECIAL < 36)
  2962.     {
  2963.       mode = MODUS_PROTO+*args.SPECIAL-30;
  2964.       sprintf(filename, "%s.h", ShortBaseName);
  2965.     }
  2966.     else
  2967.       mode = MODUS_ERROR;
  2968.   }
  2969.  
  2970.   if(mode == MODUS_ERROR)
  2971.   {
  2972.     SetIoErr(ERROR_TOO_MANY_ARGS);
  2973.     End(RETURN_FAIL);
  2974.   }
  2975.  
  2976.   if(!mode)
  2977.   {
  2978.     SetIoErr(ERROR_REQUIRED_ARG_MISSING);
  2979.     End(RETURN_FAIL);
  2980.   }
  2981.  
  2982.   if(!args.TO)
  2983.     args.TO = filename;
  2984.  
  2985.   if(args.HEADER)
  2986.   {
  2987.     if(!*args.HEADER)
  2988.       args.HEADER = args.TO;
  2989.     if(!(in.file = Open(args.HEADER, MODE_OLDFILE)) ||
  2990.     !ExamineFH(in.file, fib) ||
  2991.     !(HEADER = (STRPTR) AllocRemember(&remember, (headersize = fib->fib_Size)+1, MEMF_ANY|MEMF_CLEAR)) ||
  2992.     Read(in.file, HEADER, headersize) != headersize)
  2993.       End(RETURN_FAIL);
  2994.     if(args.HEADER == args.TO)
  2995.       FindHeader();
  2996.     Close(in.file);
  2997.     in.file = 0;
  2998.   }
  2999.  
  3000.   if(!(out.file = Open(args.TO, MODE_NEWFILE)))
  3001.     End(RETURN_FAIL);
  3002.  
  3003.   SetIoErr(0);
  3004.  
  3005.   if(mode == MODUS_PRAGMA)
  3006.     mode = CreatePragmaFile();
  3007.   else if(mode >= MODUS_PROTO)
  3008.     mode = CreateProtoFile(mode-MODUS_PROTO+1);
  3009.   else if(mode >= MODUS_LVO)
  3010.     mode = CreateLVOFile(mode-MODUS_LVO+1);
  3011.   else if(mode == MODUS_LOCALDATA)
  3012.     mode = CreateLocalData();
  3013.   else if(mode)             /* MODUS_STUBTEXT starts with 1 */
  3014.     mode = CreateAsmStubs(mode);
  3015.  
  3016.   if(!mode)
  3017.   {
  3018.     DoError(Output_Error ? ERR_UNKNOWN_ERROR : ERR_WRITING_FILE, 0);
  3019.     End(RETURN_FAIL);
  3020.   }
  3021.  
  3022.   End(RETURN_OK);
  3023. }
  3024.  
  3025. void end(void)
  3026. {
  3027.   if(fib)        FreeDosObject(DOS_FIB, fib);
  3028.   if(in.file)        Close(in.file);
  3029.   if(out.file)
  3030.   {
  3031.     Out(out.size);    /* clears Output-Buffer */
  3032.     Close(out.file);
  3033.   }
  3034.   if(oldfh)        CurrentDir(oldfh);
  3035.   if(lock)        UnLock(lock);
  3036.   if(remember)        FreeRemember(&remember, TRUE);
  3037.   if(IntuitionBase)    CloseLibrary((struct Library *) IntuitionBase);
  3038.   if(rda)
  3039.   {
  3040.     FreeArgs(rda);
  3041.     FreeDosObject(DOS_RDARGS, rda);
  3042.   }
  3043. }
  3044.